mirror of
https://github.com/finos/SymphonyElectron.git
synced 2025-02-25 18:55:29 -06:00
Merge remote-tracking branch 'upstream/skynet' into SEARCH-197
# Conflicts: # js/main.js
This commit is contained in:
commit
1bbb1f3ff0
3
.gitignore
vendored
3
.gitignore
vendored
@ -26,4 +26,5 @@ installer/mac/build/
|
|||||||
installer/mac/SymphonySettingsPlugin/SymphonySettingsPlugin.xcodeproj/xcuserdata
|
installer/mac/SymphonySettingsPlugin/SymphonySettingsPlugin.xcodeproj/xcuserdata
|
||||||
installer/mac/SymphonySettingsPlugin/SymphonySettingsPlugin.xcodeproj/project.xcworkspace/xcuserdata
|
installer/mac/SymphonySettingsPlugin/SymphonySettingsPlugin.xcodeproj/project.xcworkspace/xcuserdata
|
||||||
installer/win/Symphony-x64-cache
|
installer/win/Symphony-x64-cache
|
||||||
installer/win/Symphony-x64-SetupFiles
|
installer/win/Symphony-x64-SetupFiles
|
||||||
|
package-lock.json
|
||||||
|
@ -57,5 +57,11 @@ In order to achieve those goals Symphony is participating and working in close c
|
|||||||
- code coverage reports are placed in dir: converage
|
- code coverage reports are placed in dir: converage
|
||||||
- tests are located in dir: tests
|
- tests are located in dir: tests
|
||||||
|
|
||||||
|
## Logging
|
||||||
|
- Local logging is enabled for dev environments using the module [electron-log](https://www.npmjs.com/package/electron-log)
|
||||||
|
- On macOS, the logs are stored under `~/Library/Logs/<app name>/log.log`
|
||||||
|
- On Windows, the logs are stored under `%USERPROFILE%\AppData\Roaming\<app name>\log.log`
|
||||||
|
- Remote logging is enabled for local and production cases and are sent to the backend server via the remote objects
|
||||||
|
|
||||||
## Misc notes
|
## Misc notes
|
||||||
If desiring to run against server without proper cert use cmd line option: --ignore-certificate-errors
|
If desiring to run against server without proper cert use cmd line option: --ignore-certificate-errors
|
||||||
|
@ -6,5 +6,10 @@
|
|||||||
"notificationSettings": {
|
"notificationSettings": {
|
||||||
"position": "upper-right",
|
"position": "upper-right",
|
||||||
"display": ""
|
"display": ""
|
||||||
|
},
|
||||||
|
"crashReporter": {
|
||||||
|
"submitURL": "https://localhost:1127/post",
|
||||||
|
"companyName": "Symphony",
|
||||||
|
"uploadToServer": false
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -16,7 +16,7 @@
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label for='image'>image url:</label>
|
<label for='image'>image url:</label>
|
||||||
<input type='text' id='image' value='https://lh3.googleusercontent.com/-s2PXL6wWMCc/AAAAAAAAAAI/AAAAAAAAAAA/AAomvV2gUNMMeFsOijwVVpihfg_anpKWQA/s32-c-mo/photo.jpg'/>
|
<input type='text' id='image' value='https://avatars0.githubusercontent.com/u/13243259?v=4&s=460'/>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label for='flash'>flash:</label>
|
<label for='flash'>flash:</label>
|
||||||
@ -37,6 +37,13 @@
|
|||||||
<button id='open-config-win'>Open configure window</button>
|
<button id='open-config-win'>Open configure window</button>
|
||||||
<br>
|
<br>
|
||||||
<hr>
|
<hr>
|
||||||
|
<p>
|
||||||
|
Crash Process:
|
||||||
|
<p>
|
||||||
|
<button id='crash'>Crash Renderer</button>
|
||||||
|
</p>
|
||||||
|
<br>
|
||||||
|
<hr>
|
||||||
<p>Badge Count:<p>
|
<p>Badge Count:<p>
|
||||||
<button id='inc-badge'>increment badge count</button>
|
<button id='inc-badge'>increment badge count</button>
|
||||||
<br>
|
<br>
|
||||||
@ -172,6 +179,12 @@
|
|||||||
console.log('bounds changed for=', arg)
|
console.log('bounds changed for=', arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// crash the renderer process
|
||||||
|
const crash = document.getElementById('crash');
|
||||||
|
crash.addEventListener('click', function () {
|
||||||
|
ssf.crashRendererProcess();
|
||||||
|
});
|
||||||
|
|
||||||
var getSources = document.getElementById('get-sources');
|
var getSources = document.getElementById('get-sources');
|
||||||
getSources.addEventListener('click', function() {
|
getSources.addEventListener('click', function() {
|
||||||
ssf.getMediaSources({types: ['window', 'screen']}, function(error, sources) {
|
ssf.getMediaSources({types: ['window', 'screen']}, function(error, sources) {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>BuildMachineOSBuild</key>
|
<key>BuildMachineOSBuild</key>
|
||||||
<string>16F73</string>
|
<string>17A405</string>
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>en</string>
|
<string>en</string>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
@ -27,17 +27,17 @@
|
|||||||
<key>DTCompiler</key>
|
<key>DTCompiler</key>
|
||||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||||
<key>DTPlatformBuild</key>
|
<key>DTPlatformBuild</key>
|
||||||
<string>8E3004b</string>
|
<string>9A1004</string>
|
||||||
<key>DTPlatformVersion</key>
|
<key>DTPlatformVersion</key>
|
||||||
<string>GM</string>
|
<string>GM</string>
|
||||||
<key>DTSDKBuild</key>
|
<key>DTSDKBuild</key>
|
||||||
<string>16E185</string>
|
<string>17A360</string>
|
||||||
<key>DTSDKName</key>
|
<key>DTSDKName</key>
|
||||||
<string>macosx10.12</string>
|
<string>macosx10.13</string>
|
||||||
<key>DTXcode</key>
|
<key>DTXcode</key>
|
||||||
<string>0833</string>
|
<string>0901</string>
|
||||||
<key>DTXcodeBuild</key>
|
<key>DTXcodeBuild</key>
|
||||||
<string>8E3004b</string>
|
<string>9A1004</string>
|
||||||
<key>InstallerSectionTitle</key>
|
<key>InstallerSectionTitle</key>
|
||||||
<string>Pod Settings</string>
|
<string>Pod Settings</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -6,7 +6,7 @@
|
|||||||
<dict>
|
<dict>
|
||||||
<key>Resources/Base.lproj/MyInstallerPane.nib</key>
|
<key>Resources/Base.lproj/MyInstallerPane.nib</key>
|
||||||
<data>
|
<data>
|
||||||
5MlJroM8UDQ/u/OkMCiK9J3aK/o=
|
TF/AqkGdS25ttnHMS1l76ES81/w=
|
||||||
</data>
|
</data>
|
||||||
<key>Resources/InstallerSections.plist</key>
|
<key>Resources/InstallerSections.plist</key>
|
||||||
<data>
|
<data>
|
||||||
@ -37,11 +37,11 @@
|
|||||||
<dict>
|
<dict>
|
||||||
<key>hash</key>
|
<key>hash</key>
|
||||||
<data>
|
<data>
|
||||||
5MlJroM8UDQ/u/OkMCiK9J3aK/o=
|
TF/AqkGdS25ttnHMS1l76ES81/w=
|
||||||
</data>
|
</data>
|
||||||
<key>hash2</key>
|
<key>hash2</key>
|
||||||
<data>
|
<data>
|
||||||
KL0ObYrvW43xgEFaDXdRTINfN6qOdiK1EqrvpTusCao=
|
gxXMI4SoTYE7jYkP5QJ7i804TUXR4x8LGSh99n9qers=
|
||||||
</data>
|
</data>
|
||||||
</dict>
|
</dict>
|
||||||
<key>Resources/InstallerSections.plist</key>
|
<key>Resources/InstallerSections.plist</key>
|
||||||
|
@ -92,7 +92,7 @@
|
|||||||
3A10EBC71ED4336D0083702F /* Project object */ = {
|
3A10EBC71ED4336D0083702F /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastUpgradeCheck = 0830;
|
LastUpgradeCheck = 0900;
|
||||||
ORGANIZATIONNAME = Symphony;
|
ORGANIZATIONNAME = Symphony;
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
3A10EBCE1ED4336D0083702F = {
|
3A10EBCE1ED4336D0083702F = {
|
||||||
@ -183,7 +183,9 @@
|
|||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CLANG_ENABLE_OBJC_ARC = YES;
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
@ -191,7 +193,11 @@
|
|||||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
CLANG_WARN_INT_CONVERSION = YES;
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
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_SUSPICIOUS_MOVE = YES;
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
@ -231,7 +237,9 @@
|
|||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CLANG_ENABLE_OBJC_ARC = YES;
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
@ -239,7 +247,11 @@
|
|||||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
CLANG_WARN_INT_CONVERSION = YES;
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
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_SUSPICIOUS_MOVE = YES;
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "0830"
|
LastUpgradeVersion = "0900"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
@ -26,6 +26,7 @@
|
|||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
language = ""
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
<Testables>
|
<Testables>
|
||||||
</Testables>
|
</Testables>
|
||||||
@ -36,6 +37,7 @@
|
|||||||
buildConfiguration = "Release"
|
buildConfiguration = "Release"
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
language = ""
|
||||||
launchStyle = "0"
|
launchStyle = "0"
|
||||||
useCustomWorkingDirectory = "NO"
|
useCustomWorkingDirectory = "NO"
|
||||||
ignoresPersistentStateOnLaunch = "NO"
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="12121" systemVersion="16F73" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13196" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="12121"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13196"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
<customObject id="-2" userLabel="File's Owner" customClass="InstallerSection">
|
<customObject id="-2" userLabel="File's Owner" customClass="InstallerSection">
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="firstPane" destination="Qsn-FY-4qK" id="Dhh-1H-QYh"/>
|
<outlet property="firstPane" destination="Qsn-FY-4qK" id="Dhh-1H-QYh"/>
|
||||||
|
<outlet property="podUrlAlertTextBox" destination="wzk-BB-itI" id="QhW-ay-Yma"/>
|
||||||
</connections>
|
</connections>
|
||||||
</customObject>
|
</customObject>
|
||||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||||
@ -20,6 +21,7 @@
|
|||||||
<outlet property="contentView" destination="TUK-W2-vig" id="gTd-A7-dof"/>
|
<outlet property="contentView" destination="TUK-W2-vig" id="gTd-A7-dof"/>
|
||||||
<outlet property="minimizeOnCloseCheckBox" destination="XPe-yO-v9Y" id="ewr-3C-eNJ"/>
|
<outlet property="minimizeOnCloseCheckBox" destination="XPe-yO-v9Y" id="ewr-3C-eNJ"/>
|
||||||
<outlet property="parentSection" destination="-2" id="FB7-UV-e8k"/>
|
<outlet property="parentSection" destination="-2" id="FB7-UV-e8k"/>
|
||||||
|
<outlet property="podUrlAlertTextBox" destination="wzk-BB-itI" id="Kab-Hu-5vF"/>
|
||||||
<outlet property="podUrlTextBox" destination="uwa-xi-M5X" id="vLY-gf-Cu7"/>
|
<outlet property="podUrlTextBox" destination="uwa-xi-M5X" id="vLY-gf-Cu7"/>
|
||||||
</connections>
|
</connections>
|
||||||
</customObject>
|
</customObject>
|
||||||
@ -27,7 +29,7 @@
|
|||||||
<rect key="frame" x="0.0" y="0.0" width="418" height="330"/>
|
<rect key="frame" x="0.0" y="0.0" width="418" height="330"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kEO-Mr-GRW">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="kEO-Mr-GRW">
|
||||||
<rect key="frame" x="8" y="186" width="182" height="43"/>
|
<rect key="frame" x="8" y="186" width="182" height="43"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="Pod Url (This is where Symphony will be installed)" id="iRN-3c-tUz">
|
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="Pod Url (This is where Symphony will be installed)" id="iRN-3c-tUz">
|
||||||
@ -36,8 +38,8 @@
|
|||||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iAw-NP-Tbm">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="iAw-NP-Tbm">
|
||||||
<rect key="frame" x="8" y="95" width="188" height="28"/>
|
<rect key="frame" x="8" y="75" width="188" height="28"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Minimize Symphony on Close" id="z1k-Zj-Big">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Minimize Symphony on Close" id="z1k-Zj-Big">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@ -45,8 +47,8 @@
|
|||||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="KOx-3P-dPz">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="KOx-3P-dPz">
|
||||||
<rect key="frame" x="8" y="139" width="146" height="28"/>
|
<rect key="frame" x="8" y="119" width="146" height="28"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Auto-launch Symphony" id="9id-I6-Bxu">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Auto-launch Symphony" id="9id-I6-Bxu">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@ -55,7 +57,7 @@
|
|||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="XPe-yO-v9Y">
|
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="XPe-yO-v9Y">
|
||||||
<rect key="frame" x="209" y="105" width="22" height="18"/>
|
<rect key="frame" x="194" y="85" width="22" height="18"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<buttonCell key="cell" type="check" bezelStyle="regularSquare" imagePosition="left" inset="2" id="uvu-EE-3sp">
|
<buttonCell key="cell" type="check" bezelStyle="regularSquare" imagePosition="left" inset="2" id="uvu-EE-3sp">
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
@ -63,24 +65,24 @@
|
|||||||
</buttonCell>
|
</buttonCell>
|
||||||
</button>
|
</button>
|
||||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zJM-2d-YYz">
|
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zJM-2d-YYz">
|
||||||
<rect key="frame" x="209" y="149" width="22" height="18"/>
|
<rect key="frame" x="194" y="129" width="22" height="18"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<buttonCell key="cell" type="check" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="o5T-Og-ooq">
|
<buttonCell key="cell" type="check" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="o5T-Og-ooq">
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
</buttonCell>
|
</buttonCell>
|
||||||
</button>
|
</button>
|
||||||
<textField verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="uwa-xi-M5X">
|
<textField toolTip="Ex: https://my.symphony.com" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="uwa-xi-M5X">
|
||||||
<rect key="frame" x="211" y="197" width="192" height="32"/>
|
<rect key="frame" x="196" y="197" width="207" height="32"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" alignment="left" title="my.symphony.com" placeholderString="Ex: my.symphony.com" drawsBackground="YES" id="5g9-ba-etY">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" alignment="left" title="https://corporate.symphony.com" placeholderString="Ex: https://corporate.symphony.com" drawsBackground="YES" id="5g9-ba-etY">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="UYr-oC-RgI">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="UYr-oC-RgI">
|
||||||
<rect key="frame" x="8" y="51" width="168" height="28"/>
|
<rect key="frame" x="8" y="31" width="168" height="28"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Symphony is always on top" id="7pE-fR-PoD">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Symphony is always on top" id="7pE-fR-PoD">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@ -89,13 +91,22 @@
|
|||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8EB-K5-hjN">
|
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8EB-K5-hjN">
|
||||||
<rect key="frame" x="209" y="61" width="22" height="18"/>
|
<rect key="frame" x="194" y="41" width="22" height="18"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<buttonCell key="cell" type="check" bezelStyle="regularSquare" imagePosition="left" inset="2" id="chP-mD-3E9">
|
<buttonCell key="cell" type="check" bezelStyle="regularSquare" imagePosition="left" inset="2" id="chP-mD-3E9">
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
</buttonCell>
|
</buttonCell>
|
||||||
</button>
|
</button>
|
||||||
|
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" allowsExpansionToolTips="YES" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="wzk-BB-itI">
|
||||||
|
<rect key="frame" x="194" y="171" width="211" height="20"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
|
<textFieldCell key="cell" sendsActionOnEndEditing="YES" id="xnq-4j-scy">
|
||||||
|
<font key="font" metaFont="smallSystem"/>
|
||||||
|
<color key="textColor" red="0.92622652202072542" green="0.44039531974578455" blue="0.39870774994839908" alpha="0.84999999999999998" colorSpace="custom" customColorSpace="displayP3"/>
|
||||||
|
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
</subviews>
|
</subviews>
|
||||||
</customView>
|
</customView>
|
||||||
</objects>
|
</objects>
|
||||||
|
@ -7,11 +7,12 @@
|
|||||||
|
|
||||||
#import <InstallerPlugins/InstallerPlugins.h>
|
#import <InstallerPlugins/InstallerPlugins.h>
|
||||||
|
|
||||||
@interface MyInstallerPane : InstallerPane
|
@interface MyInstallerPane : InstallerPane<NSTextFieldDelegate>
|
||||||
|
|
||||||
@property (weak) IBOutlet NSButton *minimizeOnCloseCheckBox;
|
@property (weak) IBOutlet NSButton *minimizeOnCloseCheckBox;
|
||||||
@property (weak) IBOutlet NSButton *autoLaunchCheckBox;
|
@property (weak) IBOutlet NSButton *autoLaunchCheckBox;
|
||||||
@property (weak) IBOutlet NSTextField *podUrlTextBox;
|
@property (weak) IBOutlet NSTextField *podUrlTextBox;
|
||||||
@property (weak) IBOutlet NSButton *alwaysOnTopCheckBox;
|
@property (weak) IBOutlet NSButton *alwaysOnTopCheckBox;
|
||||||
|
@property (weak) IBOutlet NSTextField *podUrlAlertTextBox;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -14,21 +14,40 @@
|
|||||||
return [[NSBundle bundleForClass:[self class]] localizedStringForKey:@"PaneTitle" value:nil table:nil];
|
return [[NSBundle bundleForClass:[self class]] localizedStringForKey:@"PaneTitle" value:nil table:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)willExitPane:(InstallerSectionDirection)dir {
|
- (void)willEnterPane:(InstallerSectionDirection)dir {
|
||||||
|
// By default, set the value of the error message textbox to an empty string
|
||||||
// Set the default protocol to https
|
[_podUrlAlertTextBox setTitleWithMnemonic:@""];
|
||||||
NSString *protocol = @"https://";
|
}
|
||||||
|
|
||||||
|
- (BOOL)shouldExitPane:(InstallerSectionDirection)dir {
|
||||||
|
|
||||||
NSString *podUrl = [_podUrlTextBox stringValue];
|
NSString *podUrl = [_podUrlTextBox stringValue];
|
||||||
|
|
||||||
// If the pod url is empty, by default, set it to my.symphony.com
|
// Check if the url contains a protocol, if not, prepend https to it
|
||||||
if ([podUrl length] == 0) {
|
NSString *prefix = @"https://";
|
||||||
podUrl = @"my.symphony.com";
|
if (![podUrl hasPrefix:prefix]) {
|
||||||
|
podUrl = [prefix stringByAppendingString:podUrl];
|
||||||
|
[_podUrlTextBox setStringValue:podUrl];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the final url
|
// Now, validate the url against a url regex
|
||||||
NSString *finalUrl = [protocol stringByAppendingString: podUrl];
|
NSString *regex = @"^((?:http:\/\/)|(?:https:\/\/))(www.)?((?:[a-zA-Z0-9]+\.[a-z]{3})|(?:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?::\d+)?))([\/a-zA-Z0-9\.]*)$";
|
||||||
|
NSPredicate *podUrlTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
|
||||||
|
if ([podUrlTest evaluateWithObject:podUrl]) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In case of an invalid url, display the message under the pod url text box
|
||||||
|
// and don't go to the next screen, hence return NO
|
||||||
|
[_podUrlAlertTextBox setTitleWithMnemonic:@"Please enter a valid Pod url."];
|
||||||
|
return NO;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)willExitPane:(InstallerSectionDirection)dir {
|
||||||
|
|
||||||
|
NSString *podUrl = [_podUrlTextBox stringValue];
|
||||||
|
|
||||||
// By default, set autoLaunchOnStart to true
|
// By default, set autoLaunchOnStart to true
|
||||||
NSString *autoLaunchOnStart = @"true";
|
NSString *autoLaunchOnStart = @"true";
|
||||||
|
|
||||||
@ -52,7 +71,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create an array with the selected options
|
// Create an array with the selected options
|
||||||
NSArray *symSettings = [[NSArray alloc] initWithObjects:finalUrl, minimizeOnClose, autoLaunchOnStart, alwaysOnTop, nil];
|
NSArray *symSettings = [[NSArray alloc] initWithObjects:podUrl, minimizeOnClose, autoLaunchOnStart, alwaysOnTop, nil];
|
||||||
|
|
||||||
// Create a string from the array with new-line as the separator
|
// Create a string from the array with new-line as the separator
|
||||||
NSString *symSettingsString = [symSettings componentsJoinedByString:@"\n"];
|
NSString *symSettingsString = [symSettings componentsJoinedByString:@"\n"];
|
||||||
|
@ -432,6 +432,12 @@
|
|||||||
</dict>
|
</dict>
|
||||||
<key>PAYLOAD_TYPE</key>
|
<key>PAYLOAD_TYPE</key>
|
||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
|
<key>SHOW_INVISIBLE</key>
|
||||||
|
<false/>
|
||||||
|
<key>SPLIT_FORKS</key>
|
||||||
|
<true/>
|
||||||
|
<key>TREAT_MISSING_FILES_AS_WARNING</key>
|
||||||
|
<false/>
|
||||||
<key>VERSION</key>
|
<key>VERSION</key>
|
||||||
<integer>4</integer>
|
<integer>4</integer>
|
||||||
</dict>
|
</dict>
|
||||||
@ -453,15 +459,27 @@
|
|||||||
<integer>1</integer>
|
<integer>1</integer>
|
||||||
<key>CONCLUSION_ACTION</key>
|
<key>CONCLUSION_ACTION</key>
|
||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
|
<key>FOLLOW_SYMBOLIC_LINKS</key>
|
||||||
|
<false/>
|
||||||
<key>IDENTIFIER</key>
|
<key>IDENTIFIER</key>
|
||||||
<string>com.symphony.symphony-desktop</string>
|
<string>com.symphony.symphony-desktop</string>
|
||||||
|
<key>LOCATION</key>
|
||||||
|
<integer>0</integer>
|
||||||
<key>NAME</key>
|
<key>NAME</key>
|
||||||
<string>Symphony</string>
|
<string>Symphony</string>
|
||||||
<key>OVERWRITE_PERMISSIONS</key>
|
<key>OVERWRITE_PERMISSIONS</key>
|
||||||
<false/>
|
<false/>
|
||||||
|
<key>PAYLOAD_SIZE</key>
|
||||||
|
<integer>-1</integer>
|
||||||
|
<key>RELOCATABLE</key>
|
||||||
|
<false/>
|
||||||
|
<key>USE_HFS+_COMPRESSION</key>
|
||||||
|
<false/>
|
||||||
<key>VERSION</key>
|
<key>VERSION</key>
|
||||||
<string>1.0.1</string>
|
<string>2.0.0</string>
|
||||||
</dict>
|
</dict>
|
||||||
|
<key>TYPE</key>
|
||||||
|
<integer>0</integer>
|
||||||
<key>UUID</key>
|
<key>UUID</key>
|
||||||
<string>91776F5A-09FA-4631-A17C-BE8B5C83AF81</string>
|
<string>91776F5A-09FA-4631-A17C-BE8B5C83AF81</string>
|
||||||
</dict>
|
</dict>
|
||||||
@ -499,7 +517,7 @@
|
|||||||
<integer>3</integer>
|
<integer>3</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>CUSTOM</key>
|
<key>CUSTOM</key>
|
||||||
<integer>1</integer>
|
<true/>
|
||||||
<key>SCALING</key>
|
<key>SCALING</key>
|
||||||
<integer>1</integer>
|
<integer>1</integer>
|
||||||
</dict>
|
</dict>
|
||||||
@ -537,8 +555,6 @@
|
|||||||
<dict/>
|
<dict/>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
<key>INSTALLATION TYPE</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>MODE</key>
|
<key>MODE</key>
|
||||||
<integer>1</integer>
|
<integer>1</integer>
|
||||||
</dict>
|
</dict>
|
||||||
@ -631,8 +647,6 @@
|
|||||||
</dict>
|
</dict>
|
||||||
<key>LICENSE</key>
|
<key>LICENSE</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>KEYWORDS</key>
|
|
||||||
<dict/>
|
|
||||||
<key>LOCALIZATIONS</key>
|
<key>LOCALIZATIONS</key>
|
||||||
<array/>
|
<array/>
|
||||||
<key>MODE</key>
|
<key>MODE</key>
|
||||||
@ -665,10 +679,6 @@
|
|||||||
<dict>
|
<dict>
|
||||||
<key>LIST</key>
|
<key>LIST</key>
|
||||||
<array/>
|
<array/>
|
||||||
<key>POSTINSTALL_PATH</key>
|
|
||||||
<dict/>
|
|
||||||
<key>PREINSTALL_PATH</key>
|
|
||||||
<dict/>
|
|
||||||
<key>RESOURCES</key>
|
<key>RESOURCES</key>
|
||||||
<array/>
|
<array/>
|
||||||
<key>ROOT_VOLUME_ONLY</key>
|
<key>ROOT_VOLUME_ONLY</key>
|
||||||
@ -676,8 +686,6 @@
|
|||||||
</dict>
|
</dict>
|
||||||
<key>PROJECT_SETTINGS</key>
|
<key>PROJECT_SETTINGS</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>ADVANCED_OPTIONS</key>
|
|
||||||
<dict/>
|
|
||||||
<key>BUILD_FORMAT</key>
|
<key>BUILD_FORMAT</key>
|
||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
<key>BUILD_PATH</key>
|
<key>BUILD_PATH</key>
|
||||||
@ -857,6 +865,10 @@
|
|||||||
</array>
|
</array>
|
||||||
<key>NAME</key>
|
<key>NAME</key>
|
||||||
<string>Symphony</string>
|
<string>Symphony</string>
|
||||||
|
<key>PAYLOAD_ONLY</key>
|
||||||
|
<false/>
|
||||||
|
<key>TREAT_MISSING_PRESENTATION_DOCUMENTS_AS_WARNING</key>
|
||||||
|
<false/>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
<key>SHARED_GLOBAL_DATA</key>
|
<key>SHARED_GLOBAL_DATA</key>
|
||||||
|
@ -10,22 +10,27 @@
|
|||||||
<ROW Property="AI_ThemeStyle" Value="default" MsiKey="AI_ThemeStyle"/>
|
<ROW Property="AI_ThemeStyle" Value="default" MsiKey="AI_ThemeStyle"/>
|
||||||
<ROW Property="AI_UNINSTALLER" Value="msiexec.exe"/>
|
<ROW Property="AI_UNINSTALLER" Value="msiexec.exe"/>
|
||||||
<ROW Property="ALLUSERS" Value="1" MultiBuildValue="DefaultBuild:2"/>
|
<ROW Property="ALLUSERS" Value="1" MultiBuildValue="DefaultBuild:2"/>
|
||||||
|
<ROW Property="ALWAYS_ON_TOP_LABEL" Value="false" Type="4"/>
|
||||||
<ROW Property="ARPCOMMENTS" Value="This installer database contains the logic and data required to install [|ProductName]." ValueLocId="*"/>
|
<ROW Property="ARPCOMMENTS" Value="This installer database contains the logic and data required to install [|ProductName]." ValueLocId="*"/>
|
||||||
<ROW Property="ARPHELPLINK" Value="http://www.symphony.com"/>
|
<ROW Property="ARPHELPLINK" Value="http://www.symphony.com"/>
|
||||||
|
<ROW Property="ARPNOMODIFY" MultiBuildValue="DefaultBuild:1"/>
|
||||||
<ROW Property="ARPNOREPAIR" Value="1"/>
|
<ROW Property="ARPNOREPAIR" Value="1"/>
|
||||||
<ROW Property="ARPPRODUCTICON" Value="icon.exe" Type="8"/>
|
<ROW Property="ARPPRODUCTICON" Value="icon.exe" Type="8"/>
|
||||||
<ROW Property="ARPSYSTEMCOMPONENT" Value="1"/>
|
<ROW Property="ARPSYSTEMCOMPONENT" Value="1"/>
|
||||||
<ROW Property="ARPURLINFOABOUT" Value="http://www.symphony.com"/>
|
<ROW Property="ARPURLINFOABOUT" Value="http://www.symphony.com"/>
|
||||||
<ROW Property="AUTO_START" Value="CheckBox"/>
|
<ROW Property="AUTO_START" Value="CheckBox"/>
|
||||||
|
<ROW Property="AUTO_START_LABEL" Value="true" Type="4"/>
|
||||||
<ROW Property="BannerBitmap" Value="banner" MultiBuildValue="DefaultBuild:Banner.jpg" Type="1" MsiKey="BannerBitmap"/>
|
<ROW Property="BannerBitmap" Value="banner" MultiBuildValue="DefaultBuild:Banner.jpg" Type="1" MsiKey="BannerBitmap"/>
|
||||||
<ROW Property="CTRLS" Value="2"/>
|
<ROW Property="CTRLS" Value="2"/>
|
||||||
<ROW Property="DialogBitmap" Value="dialog" MultiBuildValue="DefaultBuild:Tabloid.jpg" Type="1" MsiKey="DialogBitmap"/>
|
<ROW Property="DialogBitmap" Value="dialog" MultiBuildValue="DefaultBuild:Tabloid.jpg" Type="1" MsiKey="DialogBitmap"/>
|
||||||
|
<ROW Property="INVALID_POD_URL" Value="valid" Type="4"/>
|
||||||
|
<ROW Property="MINIMIZE_ON_CLOSE_LABEL" Value="false" Type="4"/>
|
||||||
<ROW Property="Manufacturer" Value="Symphony"/>
|
<ROW Property="Manufacturer" Value="Symphony"/>
|
||||||
<ROW Property="POD_URL" Value="corporate.symphony.com" Type="4"/>
|
<ROW Property="POD_URL" Value="https://corporate.symphony.com" Type="4"/>
|
||||||
<ROW Property="ProductCode" Value="1033:{F17EDEB4-A15F-46B9-83E9-8652CBC886B2} " Type="16"/>
|
<ROW Property="ProductCode" Value="1033:{F17EDEB4-A15F-46B9-83E9-8652CBC886B2} " Type="16"/>
|
||||||
<ROW Property="ProductLanguage" Value="1033"/>
|
<ROW Property="ProductLanguage" Value="1033"/>
|
||||||
<ROW Property="ProductName" Value="Symphony-Electron"/>
|
<ROW Property="ProductName" Value="Symphony-Electron"/>
|
||||||
<ROW Property="ProductVersion" Value="1.0.0" Type="32"/>
|
<ROW Property="ProductVersion" Value="2.0.0" Type="32"/>
|
||||||
<ROW Property="REBOOT" MultiBuildValue="DefaultBuild:ReallySuppress"/>
|
<ROW Property="REBOOT" MultiBuildValue="DefaultBuild:ReallySuppress"/>
|
||||||
<ROW Property="RUNAPPLICATION" Value="1" Type="4"/>
|
<ROW Property="RUNAPPLICATION" Value="1" Type="4"/>
|
||||||
<ROW Property="SecureCustomProperties" Value="OLDPRODUCTS;AI_NEWERPRODUCTFOUND"/>
|
<ROW Property="SecureCustomProperties" Value="OLDPRODUCTS;AI_NEWERPRODUCTFOUND"/>
|
||||||
@ -52,7 +57,6 @@
|
|||||||
<ROW Directory="config_Dir" Directory_Parent="APPDIR" DefaultDir="config"/>
|
<ROW Directory="config_Dir" Directory_Parent="APPDIR" DefaultDir="config"/>
|
||||||
<ROW Directory="jobber_Dir" Directory_Parent="vendor_Dir" DefaultDir="jobber"/>
|
<ROW Directory="jobber_Dir" Directory_Parent="vendor_Dir" DefaultDir="jobber"/>
|
||||||
<ROW Directory="lib_Dir" Directory_Parent="spawnrx_Dir" DefaultDir="lib"/>
|
<ROW Directory="lib_Dir" Directory_Parent="spawnrx_Dir" DefaultDir="lib"/>
|
||||||
<ROW Directory="library_Dir" Directory_Parent="APPDIR" DefaultDir="library"/>
|
|
||||||
<ROW Directory="locales_Dir" Directory_Parent="APPDIR" DefaultDir="locales"/>
|
<ROW Directory="locales_Dir" Directory_Parent="APPDIR" DefaultDir="locales"/>
|
||||||
<ROW Directory="node_modules_Dir" Directory_Parent="app.asar.unpacked_Dir" DefaultDir="NODE_M~1|node_modules"/>
|
<ROW Directory="node_modules_Dir" Directory_Parent="app.asar.unpacked_Dir" DefaultDir="NODE_M~1|node_modules"/>
|
||||||
<ROW Directory="paulcbetts_Dir" Directory_Parent="node_modules_Dir" DefaultDir="@PAULC~1|@paulcbetts"/>
|
<ROW Directory="paulcbetts_Dir" Directory_Parent="node_modules_Dir" DefaultDir="@PAULC~1|@paulcbetts"/>
|
||||||
@ -64,7 +68,8 @@
|
|||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiCompsComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiCompsComponent">
|
||||||
<ROW Component="AI_CustomARPName" ComponentId="{2817ACD9-F494-4729-9830-111EF3311CFA}" Directory_="APPDIR" Attributes="4" KeyPath="DisplayName" Options="1"/>
|
<ROW Component="AI_CustomARPName" ComponentId="{2817ACD9-F494-4729-9830-111EF3311CFA}" Directory_="APPDIR" Attributes="4" KeyPath="DisplayName" Options="1"/>
|
||||||
<ROW Component="Jobber.exe" ComponentId="{A24482DB-EF3B-4FCA-8482-C7F034F7816C}" Directory_="jobber_Dir" Attributes="0" KeyPath="Jobber.exe"/>
|
<ROW Component="AI_DisableModify" ComponentId="{DA4E8013-2F4B-493A-90A8-BD729DA7EE2C}" Directory_="APPDIR" Attributes="260" KeyPath="NoModify" Options="1"/>
|
||||||
|
<ROW Component="Jobber.exe" ComponentId="{D019D33C-26A6-400F-9C74-D862032D1A5B}" Directory_="jobber_Dir" Attributes="0" KeyPath="Jobber.exe"/>
|
||||||
<ROW Component="PodUrl" ComponentId="{EA80D82D-BC65-4075-A9A8-F53E2B2513CE}" Directory_="APPDIR" Attributes="260" KeyPath="PodUrl"/>
|
<ROW Component="PodUrl" ComponentId="{EA80D82D-BC65-4075-A9A8-F53E2B2513CE}" Directory_="APPDIR" Attributes="260" KeyPath="PodUrl"/>
|
||||||
<ROW Component="ProductInformation" ComponentId="{8B92B687-8AE0-4A5C-B6AB-5D1854009CEA}" Directory_="APPDIR" Attributes="4" KeyPath="Version"/>
|
<ROW Component="ProductInformation" ComponentId="{8B92B687-8AE0-4A5C-B6AB-5D1854009CEA}" Directory_="APPDIR" Attributes="4" KeyPath="Version"/>
|
||||||
<ROW Component="ScreenSnippet.exe" ComponentId="{B92951AB-9E69-4970-A3B5-B4E5C32F3477}" Directory_="APPDIR" Attributes="0" KeyPath="ScreenSnippet.exe"/>
|
<ROW Component="ScreenSnippet.exe" ComponentId="{B92951AB-9E69-4970-A3B5-B4E5C32F3477}" Directory_="APPDIR" Attributes="0" KeyPath="ScreenSnippet.exe"/>
|
||||||
@ -72,7 +77,7 @@
|
|||||||
<ROW Component="Symphony.config" ComponentId="{644A231D-2C96-4D3D-ADB0-7820DA373499}" Directory_="config_Dir" Attributes="0" KeyPath="Symphony.config_1" Type="0"/>
|
<ROW Component="Symphony.config" ComponentId="{644A231D-2C96-4D3D-ADB0-7820DA373499}" Directory_="config_Dir" Attributes="0" KeyPath="Symphony.config_1" Type="0"/>
|
||||||
<ROW Component="Symphony.exe" ComponentId="{853053E4-D96C-42FE-9AF1-52FF1F449FFD}" Directory_="APPDIR" Attributes="256" KeyPath="Symphony.exe"/>
|
<ROW Component="Symphony.exe" ComponentId="{853053E4-D96C-42FE-9AF1-52FF1F449FFD}" Directory_="APPDIR" Attributes="256" KeyPath="Symphony.exe"/>
|
||||||
<ROW Component="am.pak" ComponentId="{76F935B8-6077-4C7A-AD1B-77E2DBA856CC}" Directory_="locales_Dir" Attributes="0" KeyPath="am.pak" Type="0"/>
|
<ROW Component="am.pak" ComponentId="{76F935B8-6077-4C7A-AD1B-77E2DBA856CC}" Directory_="locales_Dir" Attributes="0" KeyPath="am.pak" Type="0"/>
|
||||||
<ROW Component="ambient.d.ts" ComponentId="{DF6F3FD1-B8F8-4758-977E-B395FA0E1F23}" Directory_="src_1_Dir" Attributes="0" KeyPath="ambient.d.ts" Type="0"/>
|
<ROW Component="ambient.d.ts" ComponentId="{CAFDE1D9-C005-4ED5-A541-E08241C0EE3E}" Directory_="src_1_Dir" Attributes="0" KeyPath="ambient.d.ts" Type="0"/>
|
||||||
<ROW Component="apimswincoreconsolel110.dll" ComponentId="{24C259E2-26D5-4B36-9029-C373504B0DDD}" Directory_="APPDIR" Attributes="256" KeyPath="apimswincoreconsolel110.dll"/>
|
<ROW Component="apimswincoreconsolel110.dll" ComponentId="{24C259E2-26D5-4B36-9029-C373504B0DDD}" Directory_="APPDIR" Attributes="256" KeyPath="apimswincoreconsolel110.dll"/>
|
||||||
<ROW Component="apimswincoredatetimel110.dll" ComponentId="{E600038E-64D7-4245-9AFD-7E47970B7D6A}" Directory_="APPDIR" Attributes="256" KeyPath="apimswincoredatetimel110.dll"/>
|
<ROW Component="apimswincoredatetimel110.dll" ComponentId="{E600038E-64D7-4245-9AFD-7E47970B7D6A}" Directory_="APPDIR" Attributes="256" KeyPath="apimswincoredatetimel110.dll"/>
|
||||||
<ROW Component="apimswincoredebugl110.dll" ComponentId="{4C033829-BD86-4529-BC64-6848E1662B75}" Directory_="APPDIR" Attributes="256" KeyPath="apimswincoredebugl110.dll"/>
|
<ROW Component="apimswincoredebugl110.dll" ComponentId="{4C033829-BD86-4529-BC64-6848E1662B75}" Directory_="APPDIR" Attributes="256" KeyPath="apimswincoredebugl110.dll"/>
|
||||||
@ -115,32 +120,29 @@
|
|||||||
<ROW Component="apimswincrtutilityl110.dll" ComponentId="{C2BDE659-5902-481C-91F4-EE4B0291076C}" Directory_="APPDIR" Attributes="256" KeyPath="apimswincrtutilityl110.dll"/>
|
<ROW Component="apimswincrtutilityl110.dll" ComponentId="{C2BDE659-5902-481C-91F4-EE4B0291076C}" Directory_="APPDIR" Attributes="256" KeyPath="apimswincrtutilityl110.dll"/>
|
||||||
<ROW Component="appupdate.yml" ComponentId="{F7586760-660A-4C38-8937-138DBEC18D34}" Directory_="resources_Dir" Attributes="0" KeyPath="appupdate.yml" Type="0"/>
|
<ROW Component="appupdate.yml" ComponentId="{F7586760-660A-4C38-8937-138DBEC18D34}" Directory_="resources_Dir" Attributes="0" KeyPath="appupdate.yml" Type="0"/>
|
||||||
<ROW Component="blink_image_resources_200_percent.pak" ComponentId="{56AB17A5-B690-4CBE-A39D-512381AAAFE1}" Directory_="APPDIR" Attributes="0" KeyPath="blink_image_resources_200_percent.pak" Type="0"/>
|
<ROW Component="blink_image_resources_200_percent.pak" ComponentId="{56AB17A5-B690-4CBE-A39D-512381AAAFE1}" Directory_="APPDIR" Attributes="0" KeyPath="blink_image_resources_200_percent.pak" Type="0"/>
|
||||||
<ROW Component="cld.node" ComponentId="{1F2DDDA0-B69B-4AF4-A641-59D455B30ACB}" Directory_="Release_Dir" Attributes="256" KeyPath="cld.node" Type="0"/>
|
<ROW Component="cld.node" ComponentId="{D9F74D7B-B2E4-4ED8-A023-A54A98AE3F96}" Directory_="Release_Dir" Attributes="256" KeyPath="cld.node" Type="0"/>
|
||||||
<ROW Component="d3dcompiler_47.dll" ComponentId="{C7B87C02-3116-43A8-A70B-3592B70E6AC8}" Directory_="APPDIR" Attributes="256" KeyPath="d3dcompiler_47.dll"/>
|
<ROW Component="d3dcompiler_47.dll" ComponentId="{C7B87C02-3116-43A8-A70B-3592B70E6AC8}" Directory_="APPDIR" Attributes="256" KeyPath="d3dcompiler_47.dll"/>
|
||||||
<ROW Component="ffmpeg.dll" ComponentId="{A1C4A332-3490-44D8-A5C9-9523889B488B}" Directory_="APPDIR" Attributes="256" KeyPath="ffmpeg.dll"/>
|
<ROW Component="ffmpeg.dll" ComponentId="{A1C4A332-3490-44D8-A5C9-9523889B488B}" Directory_="APPDIR" Attributes="256" KeyPath="ffmpeg.dll"/>
|
||||||
<ROW Component="index.d.ts" ComponentId="{FB146550-23F5-45DD-82E4-90609B0C6562}" Directory_="src_Dir" Attributes="0" KeyPath="index.d.ts" Type="0"/>
|
<ROW Component="index.d.ts" ComponentId="{74D261F1-A6C5-49DD-8554-E48337CC04AF}" Directory_="src_Dir" Attributes="0" KeyPath="index.d.ts" Type="0"/>
|
||||||
<ROW Component="indexvalidator.exec" ComponentId="{BCBA8EF8-A2C0-4BB7-82DB-8B3C2AF655B3}" Directory_="library_Dir" Attributes="0" KeyPath="indexvalidator.exec" Type="0"/>
|
<ROW Component="index.js" ComponentId="{77C48E00-B684-4E72-ACF4-15DD0253EF43}" Directory_="lib_Dir" Attributes="0" KeyPath="index.js" Type="0"/>
|
||||||
<ROW Component="indexvalidatorx64.exe" ComponentId="{1BCA45C6-A281-4F96-AE91-2050DB312CD9}" Directory_="library_Dir" Attributes="256" KeyPath="indexvalidatorx64.exe"/>
|
|
||||||
<ROW Component="indexvalidatorx86.exe" ComponentId="{8BE192B9-D6A3-4CD9-83E5-E77634A70648}" Directory_="library_Dir" Attributes="0" KeyPath="indexvalidatorx86.exe"/>
|
|
||||||
<ROW Component="libEGL.dll" ComponentId="{8EEC76AB-3601-4D11-B13E-32EC2A38C539}" Directory_="APPDIR" Attributes="256" KeyPath="libEGL.dll"/>
|
<ROW Component="libEGL.dll" ComponentId="{8EEC76AB-3601-4D11-B13E-32EC2A38C539}" Directory_="APPDIR" Attributes="256" KeyPath="libEGL.dll"/>
|
||||||
<ROW Component="libGLESv2.dll" ComponentId="{0E8B8B21-B4C0-45C9-95D3-637FD93A4EC0}" Directory_="APPDIR" Attributes="256" KeyPath="libGLESv2.dll"/>
|
<ROW Component="libGLESv2.dll" ComponentId="{0E8B8B21-B4C0-45C9-95D3-637FD93A4EC0}" Directory_="APPDIR" Attributes="256" KeyPath="libGLESv2.dll"/>
|
||||||
<ROW Component="libsymphonysearchx64.dll" ComponentId="{5C72E1E5-9808-4DC1-B864-3E6C3434F80B}" Directory_="library_Dir" Attributes="256" KeyPath="libsymphonysearchx64.dll"/>
|
|
||||||
<ROW Component="libsymphonysearchx86.dll" ComponentId="{FEA12082-DA6F-467C-8B51-50AAAC318FA9}" Directory_="library_Dir" Attributes="0" KeyPath="libsymphonysearchx86.dll"/>
|
|
||||||
<ROW Component="msvcp140.dll" ComponentId="{93A6289C-CF23-4BB8-A579-7FDDD1D15591}" Directory_="APPDIR" Attributes="256" KeyPath="msvcp140.dll"/>
|
<ROW Component="msvcp140.dll" ComponentId="{93A6289C-CF23-4BB8-A579-7FDDD1D15591}" Directory_="APPDIR" Attributes="256" KeyPath="msvcp140.dll"/>
|
||||||
<ROW Component="node.dll" ComponentId="{C0972355-339E-438C-94A3-74174DE4C6B6}" Directory_="APPDIR" Attributes="256" KeyPath="node.dll"/>
|
<ROW Component="node.dll" ComponentId="{C0972355-339E-438C-94A3-74174DE4C6B6}" Directory_="APPDIR" Attributes="256" KeyPath="node.dll"/>
|
||||||
<ROW Component="npmignore_1" ComponentId="{3367B8BE-13CC-4957-B834-60B1574BCFDB}" Directory_="spawnrx_Dir" Attributes="0" KeyPath="npmignore_1" Type="0"/>
|
<ROW Component="node_modules" ComponentId="{A4EB33A8-FEA8-40A5-94EF-705EBE64DDC1}" Directory_="node_modules_Dir" Attributes="0"/>
|
||||||
|
<ROW Component="npmignore" ComponentId="{849CFFE2-EBC3-4430-AC8B-DEE1B66DF589}" Directory_="spawnrx_Dir" Attributes="0" KeyPath="npmignore" Type="0"/>
|
||||||
<ROW Component="ucrtbase.dll" ComponentId="{16D802A3-DAD4-4BF4-AD64-88D6F63F5D1E}" Directory_="APPDIR" Attributes="256" KeyPath="ucrtbase.dll"/>
|
<ROW Component="ucrtbase.dll" ComponentId="{16D802A3-DAD4-4BF4-AD64-88D6F63F5D1E}" Directory_="APPDIR" Attributes="256" KeyPath="ucrtbase.dll"/>
|
||||||
<ROW Component="vcruntime140.dll" ComponentId="{2542FC82-8D71-4351-8514-2C0D12772ED5}" Directory_="APPDIR" Attributes="256" KeyPath="vcruntime140.dll"/>
|
<ROW Component="vcruntime140.dll" ComponentId="{2542FC82-8D71-4351-8514-2C0D12772ED5}" Directory_="APPDIR" Attributes="256" KeyPath="vcruntime140.dll"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiFeatsComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiFeatsComponent">
|
||||||
<ROW Feature="D564007E3BBE4F85950A09B470A7CA65" Title="Visual C++ Redistributable for Visual Studio 2013 x86" Description="Visual C++ Redistributable for Visual Studio 2013 x86" Display="3" Level="1" Attributes="0" Components="AI_CustomARPName"/>
|
<ROW Feature="D564007E3BBE4F85950A09B470A7CA65" Title="Visual C++ Redistributable for Visual Studio 2013 x86" Description="Visual C++ Redistributable for Visual Studio 2013 x86" Display="3" Level="1" Attributes="0"/>
|
||||||
<ROW Feature="MainFeature" Title="MainFeature" Description="Description" Display="1" Level="1" Directory_="APPDIR" Attributes="0" Components="AI_CustomARPName Jobber.exe PodUrl ProductInformation ScreenSnippet.exe Symphony Symphony.config Symphony.exe am.pak ambient.d.ts apimswincoreconsolel110.dll apimswincoredatetimel110.dll apimswincoredebugl110.dll apimswincoreerrorhandlingl110.dll apimswincorefilel110.dll apimswincorefilel120.dll apimswincorefilel210.dll apimswincorehandlel110.dll apimswincoreheapl110.dll apimswincoreinterlockedl110.dll apimswincorelibraryloaderl110.dll apimswincorelocalizationl120.dll apimswincorememoryl110.dll apimswincorenamedpipel110.dll apimswincoreprocessenvironmentl110.dll apimswincoreprocessthreadsl110.dll apimswincoreprocessthreadsl111.dll apimswincoreprofilel110.dll apimswincorertlsupportl110.dll apimswincorestringl110.dll apimswincoresynchl110.dll apimswincoresynchl120.dll apimswincoresysinfol110.dll apimswincoretimezonel110.dll apimswincoreutill110.dll apimswincrtconiol110.dll apimswincrtconvertl110.dll apimswincrtenvironmentl110.dll apimswincrtfilesysteml110.dll apimswincrtheapl110.dll apimswincrtlocalel110.dll apimswincrtmathl110.dll apimswincrtmultibytel110.dll apimswincrtprivatel110.dll apimswincrtprocessl110.dll apimswincrtruntimel110.dll apimswincrtstdiol110.dll apimswincrtstringl110.dll apimswincrttimel110.dll apimswincrtutilityl110.dll appupdate.yml blink_image_resources_200_percent.pak cld.node d3dcompiler_47.dll ffmpeg.dll index.d.ts indexvalidator.exec indexvalidatorx64.exe indexvalidatorx86.exe libEGL.dll libGLESv2.dll libsymphonysearchx64.dll libsymphonysearchx86.dll msvcp140.dll node.dll npmignore_1 ucrtbase.dll vcruntime140.dll"/>
|
<ROW Feature="MainFeature" Title="MainFeature" Description="Description" Display="1" Level="1" Directory_="APPDIR" Attributes="0" Components="AI_CustomARPName AI_DisableModify Jobber.exe PodUrl ProductInformation ScreenSnippet.exe Symphony Symphony.config Symphony.exe am.pak ambient.d.ts apimswincoreconsolel110.dll apimswincoredatetimel110.dll apimswincoredebugl110.dll apimswincoreerrorhandlingl110.dll apimswincorefilel110.dll apimswincorefilel120.dll apimswincorefilel210.dll apimswincorehandlel110.dll apimswincoreheapl110.dll apimswincoreinterlockedl110.dll apimswincorelibraryloaderl110.dll apimswincorelocalizationl120.dll apimswincorememoryl110.dll apimswincorenamedpipel110.dll apimswincoreprocessenvironmentl110.dll apimswincoreprocessthreadsl110.dll apimswincoreprocessthreadsl111.dll apimswincoreprofilel110.dll apimswincorertlsupportl110.dll apimswincorestringl110.dll apimswincoresynchl110.dll apimswincoresynchl120.dll apimswincoresysinfol110.dll apimswincoretimezonel110.dll apimswincoreutill110.dll apimswincrtconiol110.dll apimswincrtconvertl110.dll apimswincrtenvironmentl110.dll apimswincrtfilesysteml110.dll apimswincrtheapl110.dll apimswincrtlocalel110.dll apimswincrtmathl110.dll apimswincrtmultibytel110.dll apimswincrtprivatel110.dll apimswincrtprocessl110.dll apimswincrtruntimel110.dll apimswincrtstdiol110.dll apimswincrtstringl110.dll apimswincrttimel110.dll apimswincrtutilityl110.dll appupdate.yml blink_image_resources_200_percent.pak cld.node d3dcompiler_47.dll ffmpeg.dll index.d.ts index.js libEGL.dll libGLESv2.dll msvcp140.dll node.dll node_modules npmignore ucrtbase.dll vcruntime140.dll"/>
|
||||||
<ATTRIBUTE name="CurrentFeature" value="MainFeature"/>
|
<ATTRIBUTE name="CurrentFeature" value="MainFeature"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiFilesComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiFilesComponent">
|
||||||
<ROW File="CODE_OF_CONDUCT.md" Component_="npmignore_1" FileName="CODE_O~1.MD|CODE_OF_CONDUCT.md" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\CODE_OF_CONDUCT.md" SelfReg="false" NextFile="COPYING"/>
|
<ROW File="CODE_OF_CONDUCT.md" Component_="npmignore" FileName="CODE_O~1.MD|CODE_OF_CONDUCT.md" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\CODE_OF_CONDUCT.md" SelfReg="false" NextFile="COPYING"/>
|
||||||
<ROW File="COPYING" Component_="npmignore_1" FileName="COPYING" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\COPYING" SelfReg="false" NextFile="esdoc.json"/>
|
<ROW File="COPYING" Component_="npmignore" FileName="COPYING" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\COPYING" SelfReg="false" NextFile="esdoc.json"/>
|
||||||
<ROW File="Jobber.exe" Component_="Jobber.exe" FileName="Jobber.exe" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\vendor\jobber\Jobber.exe" SelfReg="false" NextFile="indexvalidatorx64.exe" DigSign="true"/>
|
<ROW File="Jobber.exe" Component_="Jobber.exe" FileName="Jobber.exe" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\vendor\jobber\Jobber.exe" SelfReg="false" NextFile="cld.node" DigSign="true"/>
|
||||||
<ROW File="LICENSE.electron.txt" Component_="blink_image_resources_200_percent.pak" FileName="LICENS~1.TXT|LICENSE.electron.txt" Attributes="0" SourcePath="..\..\dist\win-unpacked\LICENSE.electron.txt" SelfReg="false" NextFile="LICENSES.chromium.html"/>
|
<ROW File="LICENSE.electron.txt" Component_="blink_image_resources_200_percent.pak" FileName="LICENS~1.TXT|LICENSE.electron.txt" Attributes="0" SourcePath="..\..\dist\win-unpacked\LICENSE.electron.txt" SelfReg="false" NextFile="LICENSES.chromium.html"/>
|
||||||
<ROW File="LICENSES.chromium.html" Component_="blink_image_resources_200_percent.pak" FileName="LICENS~1.HTM|LICENSES.chromium.html" Attributes="0" SourcePath="..\..\dist\win-unpacked\LICENSES.chromium.html" SelfReg="false" NextFile="natives_blob.bin"/>
|
<ROW File="LICENSES.chromium.html" Component_="blink_image_resources_200_percent.pak" FileName="LICENS~1.HTM|LICENSES.chromium.html" Attributes="0" SourcePath="..\..\dist\win-unpacked\LICENSES.chromium.html" SelfReg="false" NextFile="natives_blob.bin"/>
|
||||||
<ROW File="ScreenSnippet.exe" Component_="ScreenSnippet.exe" FileName="SCREEN~1.EXE|ScreenSnippet.exe" Attributes="0" SourcePath="..\..\node_modules\screen-snippet\bin\Release\ScreenSnippet.exe" SelfReg="false" NextFile="apimswincoreconsolel110.dll" DigSign="true"/>
|
<ROW File="ScreenSnippet.exe" Component_="ScreenSnippet.exe" FileName="SCREEN~1.EXE|ScreenSnippet.exe" Attributes="0" SourcePath="..\..\node_modules\screen-snippet\bin\Release\ScreenSnippet.exe" SelfReg="false" NextFile="apimswincoreconsolel110.dll" DigSign="true"/>
|
||||||
@ -194,10 +196,10 @@
|
|||||||
<ROW File="bg.pak" Component_="am.pak" FileName="bg.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\bg.pak" SelfReg="false" NextFile="bn.pak"/>
|
<ROW File="bg.pak" Component_="am.pak" FileName="bg.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\bg.pak" SelfReg="false" NextFile="bn.pak"/>
|
||||||
<ROW File="blink_image_resources_200_percent.pak" Component_="blink_image_resources_200_percent.pak" FileName="BLINK_~1.PAK|blink_image_resources_200_percent.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\blink_image_resources_200_percent.pak" SelfReg="false" NextFile="content_resources_200_percent.pak"/>
|
<ROW File="blink_image_resources_200_percent.pak" Component_="blink_image_resources_200_percent.pak" FileName="BLINK_~1.PAK|blink_image_resources_200_percent.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\blink_image_resources_200_percent.pak" SelfReg="false" NextFile="content_resources_200_percent.pak"/>
|
||||||
<ROW File="bn.pak" Component_="am.pak" FileName="bn.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\bn.pak" SelfReg="false" NextFile="ca.pak"/>
|
<ROW File="bn.pak" Component_="am.pak" FileName="bn.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\bn.pak" SelfReg="false" NextFile="ca.pak"/>
|
||||||
<ROW File="build.cmd" Component_="npmignore_1" FileName="build.cmd" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\build.cmd" SelfReg="false" NextFile="build.sh"/>
|
<ROW File="build.cmd" Component_="npmignore" FileName="build.cmd" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\build.cmd" SelfReg="false" NextFile="build.sh"/>
|
||||||
<ROW File="build.sh" Component_="npmignore_1" FileName="build.sh" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\build.sh" SelfReg="false" NextFile="CODE_OF_CONDUCT.md"/>
|
<ROW File="build.sh" Component_="npmignore" FileName="build.sh" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\build.sh" SelfReg="false" NextFile="CODE_OF_CONDUCT.md"/>
|
||||||
<ROW File="ca.pak" Component_="am.pak" FileName="ca.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\ca.pak" SelfReg="false" NextFile="cs.pak"/>
|
<ROW File="ca.pak" Component_="am.pak" FileName="ca.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\ca.pak" SelfReg="false" NextFile="cs.pak"/>
|
||||||
<ROW File="cld.node" Component_="cld.node" FileName="CLD~1.NOD|cld.node" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\@paulcbetts\cld\build\Release\cld.node" SelfReg="false" NextFile="npmignore_1"/>
|
<ROW File="cld.node" Component_="cld.node" FileName="CLD~1.NOD|cld.node" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\@paulcbetts\cld\build\Release\cld.node" SelfReg="false"/>
|
||||||
<ROW File="content_resources_200_percent.pak" Component_="blink_image_resources_200_percent.pak" FileName="CONTEN~1.PAK|content_resources_200_percent.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\content_resources_200_percent.pak" SelfReg="false" NextFile="content_shell.pak"/>
|
<ROW File="content_resources_200_percent.pak" Component_="blink_image_resources_200_percent.pak" FileName="CONTEN~1.PAK|content_resources_200_percent.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\content_resources_200_percent.pak" SelfReg="false" NextFile="content_shell.pak"/>
|
||||||
<ROW File="content_shell.pak" Component_="blink_image_resources_200_percent.pak" FileName="CONTEN~2.PAK|content_shell.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\content_shell.pak" SelfReg="false" NextFile="d3dcompiler_47.dll"/>
|
<ROW File="content_shell.pak" Component_="blink_image_resources_200_percent.pak" FileName="CONTEN~2.PAK|content_shell.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\content_shell.pak" SelfReg="false" NextFile="d3dcompiler_47.dll"/>
|
||||||
<ROW File="cs.pak" Component_="am.pak" FileName="cs.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\cs.pak" SelfReg="false" NextFile="da.pak"/>
|
<ROW File="cs.pak" Component_="am.pak" FileName="cs.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\cs.pak" SelfReg="false" NextFile="da.pak"/>
|
||||||
@ -210,7 +212,7 @@
|
|||||||
<ROW File="enUS.pak" Component_="am.pak" FileName="en-US.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\en-US.pak" SelfReg="false" NextFile="es.pak"/>
|
<ROW File="enUS.pak" Component_="am.pak" FileName="en-US.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\en-US.pak" SelfReg="false" NextFile="es.pak"/>
|
||||||
<ROW File="es.pak" Component_="am.pak" FileName="es.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\es.pak" SelfReg="false" NextFile="es419.pak"/>
|
<ROW File="es.pak" Component_="am.pak" FileName="es.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\es.pak" SelfReg="false" NextFile="es419.pak"/>
|
||||||
<ROW File="es419.pak" Component_="am.pak" FileName="es-419.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\es-419.pak" SelfReg="false" NextFile="et.pak"/>
|
<ROW File="es419.pak" Component_="am.pak" FileName="es-419.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\es-419.pak" SelfReg="false" NextFile="et.pak"/>
|
||||||
<ROW File="esdoc.json" Component_="npmignore_1" FileName="ESDOC~1.JSO|esdoc.json" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\esdoc.json" SelfReg="false" NextFile="index.d.ts"/>
|
<ROW File="esdoc.json" Component_="npmignore" FileName="ESDOC~1.JSO|esdoc.json" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\esdoc.json" SelfReg="false" NextFile="index.js"/>
|
||||||
<ROW File="et.pak" Component_="am.pak" FileName="et.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\et.pak" SelfReg="false" NextFile="fa.pak"/>
|
<ROW File="et.pak" Component_="am.pak" FileName="et.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\et.pak" SelfReg="false" NextFile="fa.pak"/>
|
||||||
<ROW File="fa.pak" Component_="am.pak" FileName="fa.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\fa.pak" SelfReg="false" NextFile="fakebidi.pak"/>
|
<ROW File="fa.pak" Component_="am.pak" FileName="fa.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\fa.pak" SelfReg="false" NextFile="fakebidi.pak"/>
|
||||||
<ROW File="fakebidi.pak" Component_="am.pak" FileName="FAKE-B~1.PAK|fake-bidi.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\fake-bidi.pak" SelfReg="false" NextFile="fi.pak"/>
|
<ROW File="fakebidi.pak" Component_="am.pak" FileName="FAKE-B~1.PAK|fake-bidi.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\fake-bidi.pak" SelfReg="false" NextFile="fi.pak"/>
|
||||||
@ -225,22 +227,17 @@
|
|||||||
<ROW File="hu.pak" Component_="am.pak" FileName="hu.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\hu.pak" SelfReg="false" NextFile="id.pak"/>
|
<ROW File="hu.pak" Component_="am.pak" FileName="hu.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\hu.pak" SelfReg="false" NextFile="id.pak"/>
|
||||||
<ROW File="icudtl.dat" Component_="blink_image_resources_200_percent.pak" FileName="icudtl.dat" Attributes="0" SourcePath="..\..\dist\win-unpacked\icudtl.dat" SelfReg="false" NextFile="libEGL.dll"/>
|
<ROW File="icudtl.dat" Component_="blink_image_resources_200_percent.pak" FileName="icudtl.dat" Attributes="0" SourcePath="..\..\dist\win-unpacked\icudtl.dat" SelfReg="false" NextFile="libEGL.dll"/>
|
||||||
<ROW File="id.pak" Component_="am.pak" FileName="id.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\id.pak" SelfReg="false" NextFile="it.pak"/>
|
<ROW File="id.pak" Component_="am.pak" FileName="id.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\id.pak" SelfReg="false" NextFile="it.pak"/>
|
||||||
<ROW File="index.d.ts" Component_="index.d.ts" FileName="INDEXD~1.TS|index.d.ts" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\lib\src\index.d.ts" SelfReg="false" NextFile="index.js"/>
|
<ROW File="index.d.ts" Component_="index.d.ts" FileName="INDEXD~1.TS|index.d.ts" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\lib\src\index.d.ts" SelfReg="false" NextFile="index.js_1"/>
|
||||||
<ROW File="index.js" Component_="index.d.ts" FileName="index.js" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\lib\src\index.js" SelfReg="false" NextFile="index.js.map"/>
|
<ROW File="index.js" Component_="index.js" FileName="index.js" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\lib\index.js" SelfReg="false" NextFile="index.d.ts"/>
|
||||||
<ROW File="index.js.map" Component_="index.d.ts" FileName="INDEXJ~1.MAP|index.js.map" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\lib\src\index.js.map" SelfReg="false" NextFile="package.json_1"/>
|
<ROW File="index.js.map" Component_="index.d.ts" FileName="INDEXJ~1.MAP|index.js.map" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\lib\src\index.js.map" SelfReg="false" NextFile="package.json"/>
|
||||||
|
<ROW File="index.js_1" Component_="index.d.ts" FileName="index.js" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\lib\src\index.js" SelfReg="false" NextFile="index.js.map"/>
|
||||||
<ROW File="index.ts" Component_="ambient.d.ts" FileName="index.ts" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\src\index.ts" SelfReg="false" NextFile="tsconfig.json"/>
|
<ROW File="index.ts" Component_="ambient.d.ts" FileName="index.ts" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\src\index.ts" SelfReg="false" NextFile="tsconfig.json"/>
|
||||||
<ROW File="indexvalidator.exec" Component_="indexvalidator.exec" FileName="INDEXV~3.EXE|indexvalidator.exec" Attributes="0" SourcePath="..\..\library\indexvalidator.exec" SelfReg="false" NextFile="libsymphonysearchx64.dll"/>
|
|
||||||
<ROW File="indexvalidatorx64.exe" Component_="indexvalidatorx64.exe" FileName="INDEXV~1.EXE|indexvalidator-x64.exe" Attributes="0" SourcePath="..\..\library\indexvalidator-x64.exe" SelfReg="false" NextFile="indexvalidatorx86.exe" DigSign="true"/>
|
|
||||||
<ROW File="indexvalidatorx86.exe" Component_="indexvalidatorx86.exe" FileName="INDEXV~2.EXE|indexvalidator-x86.exe" Attributes="0" SourcePath="..\..\library\indexvalidator-x86.exe" SelfReg="false" NextFile="indexvalidator.exec" DigSign="true"/>
|
|
||||||
<ROW File="it.pak" Component_="am.pak" FileName="it.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\it.pak" SelfReg="false" NextFile="ja.pak"/>
|
<ROW File="it.pak" Component_="am.pak" FileName="it.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\it.pak" SelfReg="false" NextFile="ja.pak"/>
|
||||||
<ROW File="ja.pak" Component_="am.pak" FileName="ja.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\ja.pak" SelfReg="false" NextFile="kn.pak"/>
|
<ROW File="ja.pak" Component_="am.pak" FileName="ja.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\ja.pak" SelfReg="false" NextFile="kn.pak"/>
|
||||||
<ROW File="kn.pak" Component_="am.pak" FileName="kn.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\kn.pak" SelfReg="false" NextFile="ko.pak"/>
|
<ROW File="kn.pak" Component_="am.pak" FileName="kn.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\kn.pak" SelfReg="false" NextFile="ko.pak"/>
|
||||||
<ROW File="ko.pak" Component_="am.pak" FileName="ko.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\ko.pak" SelfReg="false" NextFile="lt.pak"/>
|
<ROW File="ko.pak" Component_="am.pak" FileName="ko.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\ko.pak" SelfReg="false" NextFile="lt.pak"/>
|
||||||
<ROW File="libEGL.dll" Component_="libEGL.dll" FileName="libEGL.dll" Attributes="0" SourcePath="..\..\dist\win-unpacked\libEGL.dll" SelfReg="false" NextFile="libGLESv2.dll"/>
|
<ROW File="libEGL.dll" Component_="libEGL.dll" FileName="libEGL.dll" Attributes="0" SourcePath="..\..\dist\win-unpacked\libEGL.dll" SelfReg="false" NextFile="libGLESv2.dll"/>
|
||||||
<ROW File="libGLESv2.dll" Component_="libGLESv2.dll" FileName="LIBGLE~1.DLL|libGLESv2.dll" Attributes="0" SourcePath="..\..\dist\win-unpacked\libGLESv2.dll" SelfReg="false" NextFile="LICENSE.electron.txt"/>
|
<ROW File="libGLESv2.dll" Component_="libGLESv2.dll" FileName="LIBGLE~1.DLL|libGLESv2.dll" Attributes="0" SourcePath="..\..\dist\win-unpacked\libGLESv2.dll" SelfReg="false" NextFile="LICENSE.electron.txt"/>
|
||||||
<ROW File="libsymphonysearch.dylib" Component_="indexvalidator.exec" FileName="LIBSYM~1.DYL|libsymphonysearch.dylib" Attributes="0" SourcePath="..\..\library\libsymphonysearch.dylib" SelfReg="false"/>
|
|
||||||
<ROW File="libsymphonysearchx64.dll" Component_="libsymphonysearchx64.dll" FileName="LIBSYM~1.DLL|libsymphonysearch-x64.dll" Attributes="0" SourcePath="..\..\library\libsymphonysearch-x64.dll" SelfReg="false" NextFile="libsymphonysearchx86.dll"/>
|
|
||||||
<ROW File="libsymphonysearchx86.dll" Component_="libsymphonysearchx86.dll" FileName="LIBSYM~2.DLL|libsymphonysearch-x86.dll" Attributes="0" SourcePath="..\..\library\libsymphonysearch-x86.dll" SelfReg="false" NextFile="libsymphonysearch.dylib"/>
|
|
||||||
<ROW File="lt.pak" Component_="am.pak" FileName="lt.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\lt.pak" SelfReg="false" NextFile="lv.pak"/>
|
<ROW File="lt.pak" Component_="am.pak" FileName="lt.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\lt.pak" SelfReg="false" NextFile="lv.pak"/>
|
||||||
<ROW File="lv.pak" Component_="am.pak" FileName="lv.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\lv.pak" SelfReg="false" NextFile="ml.pak"/>
|
<ROW File="lv.pak" Component_="am.pak" FileName="lv.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\lv.pak" SelfReg="false" NextFile="ml.pak"/>
|
||||||
<ROW File="ml.pak" Component_="am.pak" FileName="ml.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\ml.pak" SelfReg="false" NextFile="mr.pak"/>
|
<ROW File="ml.pak" Component_="am.pak" FileName="ml.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\ml.pak" SelfReg="false" NextFile="mr.pak"/>
|
||||||
@ -251,8 +248,8 @@
|
|||||||
<ROW File="nb.pak" Component_="am.pak" FileName="nb.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\nb.pak" SelfReg="false" NextFile="nl.pak"/>
|
<ROW File="nb.pak" Component_="am.pak" FileName="nb.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\nb.pak" SelfReg="false" NextFile="nl.pak"/>
|
||||||
<ROW File="nl.pak" Component_="am.pak" FileName="nl.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\nl.pak" SelfReg="false" NextFile="pl.pak"/>
|
<ROW File="nl.pak" Component_="am.pak" FileName="nl.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\nl.pak" SelfReg="false" NextFile="pl.pak"/>
|
||||||
<ROW File="node.dll" Component_="node.dll" FileName="node.dll" Attributes="0" SourcePath="..\..\dist\win-unpacked\node.dll" SelfReg="false" NextFile="snapshot_blob.bin"/>
|
<ROW File="node.dll" Component_="node.dll" FileName="node.dll" Attributes="0" SourcePath="..\..\dist\win-unpacked\node.dll" SelfReg="false" NextFile="snapshot_blob.bin"/>
|
||||||
<ROW File="npmignore_1" Component_="npmignore_1" FileName="NPMIGN~1|.npmignore" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\.npmignore" SelfReg="false" NextFile="build.cmd"/>
|
<ROW File="npmignore" Component_="npmignore" FileName="NPMIGN~1|.npmignore" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\.npmignore" SelfReg="false" NextFile="build.cmd"/>
|
||||||
<ROW File="package.json_1" Component_="npmignore_1" FileName="PACKAG~1.JSO|package.json" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\package.json" SelfReg="false" NextFile="ambient.d.ts"/>
|
<ROW File="package.json" Component_="npmignore" FileName="PACKAG~1.JSO|package.json" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\package.json" SelfReg="false" NextFile="ambient.d.ts"/>
|
||||||
<ROW File="pl.pak" Component_="am.pak" FileName="pl.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\pl.pak" SelfReg="false" NextFile="ptBR.pak"/>
|
<ROW File="pl.pak" Component_="am.pak" FileName="pl.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\pl.pak" SelfReg="false" NextFile="ptBR.pak"/>
|
||||||
<ROW File="ptBR.pak" Component_="am.pak" FileName="pt-BR.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\pt-BR.pak" SelfReg="false" NextFile="ptPT.pak"/>
|
<ROW File="ptBR.pak" Component_="am.pak" FileName="pt-BR.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\pt-BR.pak" SelfReg="false" NextFile="ptPT.pak"/>
|
||||||
<ROW File="ptPT.pak" Component_="am.pak" FileName="pt-PT.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\pt-PT.pak" SelfReg="false" NextFile="ro.pak"/>
|
<ROW File="ptPT.pak" Component_="am.pak" FileName="pt-PT.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\pt-PT.pak" SelfReg="false" NextFile="ro.pak"/>
|
||||||
@ -268,12 +265,12 @@
|
|||||||
<ROW File="te.pak" Component_="am.pak" FileName="te.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\te.pak" SelfReg="false" NextFile="th.pak"/>
|
<ROW File="te.pak" Component_="am.pak" FileName="te.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\te.pak" SelfReg="false" NextFile="th.pak"/>
|
||||||
<ROW File="th.pak" Component_="am.pak" FileName="th.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\th.pak" SelfReg="false" NextFile="tr.pak"/>
|
<ROW File="th.pak" Component_="am.pak" FileName="th.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\th.pak" SelfReg="false" NextFile="tr.pak"/>
|
||||||
<ROW File="tr.pak" Component_="am.pak" FileName="tr.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\tr.pak" SelfReg="false" NextFile="uk.pak"/>
|
<ROW File="tr.pak" Component_="am.pak" FileName="tr.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\tr.pak" SelfReg="false" NextFile="uk.pak"/>
|
||||||
<ROW File="tsconfig.json" Component_="npmignore_1" FileName="TSCONF~1.JSO|tsconfig.json" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\tsconfig.json" SelfReg="false" NextFile="tslint.json"/>
|
<ROW File="tsconfig.json" Component_="npmignore" FileName="TSCONF~1.JSO|tsconfig.json" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\tsconfig.json" SelfReg="false" NextFile="tslint.json"/>
|
||||||
<ROW File="tslint.json" Component_="npmignore_1" FileName="TSLINT~1.JSO|tslint.json" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\tslint.json" SelfReg="false" NextFile="Jobber.exe"/>
|
<ROW File="tslint.json" Component_="npmignore" FileName="TSLINT~1.JSO|tslint.json" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\tslint.json" SelfReg="false" NextFile="Jobber.exe"/>
|
||||||
<ROW File="ucrtbase.dll" Component_="ucrtbase.dll" FileName="ucrtbase.dll" Attributes="0" SourcePath="..\..\dist\win-unpacked\ucrtbase.dll" SelfReg="false" NextFile="vcruntime140.dll"/>
|
<ROW File="ucrtbase.dll" Component_="ucrtbase.dll" FileName="ucrtbase.dll" Attributes="0" SourcePath="..\..\dist\win-unpacked\ucrtbase.dll" SelfReg="false" NextFile="vcruntime140.dll"/>
|
||||||
<ROW File="ui_resources_200_percent.pak" Component_="blink_image_resources_200_percent.pak" FileName="UI_RES~1.PAK|ui_resources_200_percent.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\ui_resources_200_percent.pak" SelfReg="false" NextFile="views_resources_200_percent.pak"/>
|
<ROW File="ui_resources_200_percent.pak" Component_="blink_image_resources_200_percent.pak" FileName="UI_RES~1.PAK|ui_resources_200_percent.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\ui_resources_200_percent.pak" SelfReg="false" NextFile="views_resources_200_percent.pak"/>
|
||||||
<ROW File="uk.pak" Component_="am.pak" FileName="uk.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\uk.pak" SelfReg="false" NextFile="vi.pak"/>
|
<ROW File="uk.pak" Component_="am.pak" FileName="uk.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\uk.pak" SelfReg="false" NextFile="vi.pak"/>
|
||||||
<ROW File="vcruntime140.dll" Component_="vcruntime140.dll" FileName="VCRUNT~1.DLL|vcruntime140.dll" Attributes="0" SourcePath="..\..\dist\win-unpacked\vcruntime140.dll" SelfReg="false" NextFile="cld.node"/>
|
<ROW File="vcruntime140.dll" Component_="vcruntime140.dll" FileName="VCRUNT~1.DLL|vcruntime140.dll" Attributes="0" SourcePath="..\..\dist\win-unpacked\vcruntime140.dll" SelfReg="false" NextFile="npmignore"/>
|
||||||
<ROW File="vi.pak" Component_="am.pak" FileName="vi.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\vi.pak" SelfReg="false" NextFile="zhCN.pak"/>
|
<ROW File="vi.pak" Component_="am.pak" FileName="vi.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\vi.pak" SelfReg="false" NextFile="zhCN.pak"/>
|
||||||
<ROW File="views_resources_200_percent.pak" Component_="blink_image_resources_200_percent.pak" FileName="VIEWS_~1.PAK|views_resources_200_percent.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\views_resources_200_percent.pak" SelfReg="false" NextFile="am.pak"/>
|
<ROW File="views_resources_200_percent.pak" Component_="blink_image_resources_200_percent.pak" FileName="VIEWS_~1.PAK|views_resources_200_percent.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\views_resources_200_percent.pak" SelfReg="false" NextFile="am.pak"/>
|
||||||
<ROW File="zhCN.pak" Component_="am.pak" FileName="zh-CN.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\zh-CN.pak" SelfReg="false" NextFile="zhTW.pak"/>
|
<ROW File="zhCN.pak" Component_="am.pak" FileName="zh-CN.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\zh-CN.pak" SelfReg="false" NextFile="zhTW.pak"/>
|
||||||
@ -284,6 +281,9 @@
|
|||||||
<ROW AliasRowId="MINIMIZE_ON_CLOSE" AliasRowOperation="2" Value="true"/>
|
<ROW AliasRowId="MINIMIZE_ON_CLOSE" AliasRowOperation="2" Value="true"/>
|
||||||
<ROW AliasRowId="ALWAYS_ON_TOP" AliasRowOperation="2" Value="true"/>
|
<ROW AliasRowId="ALWAYS_ON_TOP" AliasRowOperation="2" Value="true"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
|
<COMPONENT cid="caphyon.advinst.msicomp.AiPersistentDataComponent">
|
||||||
|
<ROW PersistentRow="Symphony.config_1" Type="0" Condition="REINSTALL"/>
|
||||||
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.BuildComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.BuildComponent">
|
||||||
<ROW BuildKey="DefaultBuild" BuildName="DefaultBuild" BuildOrder="1" BuildType="1" Languages="en" InstallationType="4" UseLargeSchema="true" MsiPackageType="x64"/>
|
<ROW BuildKey="DefaultBuild" BuildName="DefaultBuild" BuildOrder="1" BuildType="1" Languages="en" InstallationType="4" UseLargeSchema="true" MsiPackageType="x64"/>
|
||||||
<ATTRIBUTE name="CurrentBuild" value="DefaultBuild"/>
|
<ATTRIBUTE name="CurrentBuild" value="DefaultBuild"/>
|
||||||
@ -310,6 +310,10 @@
|
|||||||
<ROW Fragment="VerifyRepairDlg.aip" Path="<AI_THEMES>classic\fragments\VerifyRepairDlg.aip"/>
|
<ROW Fragment="VerifyRepairDlg.aip" Path="<AI_THEMES>classic\fragments\VerifyRepairDlg.aip"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiActionTextComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiActionTextComponent">
|
||||||
|
<ROW Action="AI_AiBackupImmediate" Description="Preparing backup operation" Template="Path: [1]" DescriptionLocId="ActionText.Description.AI_AiBackupImmediate" TemplateLocId="ActionText.Template.AI_AiBackupImmediate"/>
|
||||||
|
<ROW Action="AI_AiBackupRollback" Description="Rollback backup" Template="Path: [1]" DescriptionLocId="ActionText.Description.AI_AiBackupRollback" TemplateLocId="ActionText.Template.AI_AiBackupRollback"/>
|
||||||
|
<ROW Action="AI_AiRestoreDeferred" Description="Executing restore operation" Template="Path: [1]" DescriptionLocId="ActionText.Description.AI_AiRestoreDeferred" TemplateLocId="ActionText.Template.AI_AiRestoreDeferred"/>
|
||||||
|
<ROW Action="AI_AiRestoreRollback" Description="Rollback restore" Template="Path: [1]" DescriptionLocId="ActionText.Description.AI_AiRestoreRollback" TemplateLocId="ActionText.Template.AI_AiRestoreRollback"/>
|
||||||
<ROW Action="AI_TxtUpdaterCommit" Description="Commit text file changes. " Template="Commit text file changes." DescriptionLocId="ActionText.Description.AI_TxtUpdaterCommit" TemplateLocId="ActionText.Template.AI_TxtUpdaterCommit"/>
|
<ROW Action="AI_TxtUpdaterCommit" Description="Commit text file changes. " Template="Commit text file changes." DescriptionLocId="ActionText.Description.AI_TxtUpdaterCommit" TemplateLocId="ActionText.Template.AI_TxtUpdaterCommit"/>
|
||||||
<ROW Action="AI_TxtUpdaterConfig" Description="Executing text file updates" Template="Updating text file: "[1]"" DescriptionLocId="ActionText.Description.AI_TxtUpdaterConfig" TemplateLocId="ActionText.Template.AI_TxtUpdaterConfig"/>
|
<ROW Action="AI_TxtUpdaterConfig" Description="Executing text file updates" Template="Updating text file: "[1]"" DescriptionLocId="ActionText.Description.AI_TxtUpdaterConfig" TemplateLocId="ActionText.Template.AI_TxtUpdaterConfig"/>
|
||||||
<ROW Action="AI_TxtUpdaterInstall" Description="Generating actions to configure text files updates" DescriptionLocId="ActionText.Description.AI_TxtUpdaterInstall"/>
|
<ROW Action="AI_TxtUpdaterInstall" Description="Generating actions to configure text files updates" DescriptionLocId="ActionText.Description.AI_TxtUpdaterInstall"/>
|
||||||
@ -317,6 +321,7 @@
|
|||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiBinaryComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiBinaryComponent">
|
||||||
<ROW Name="Banner.jpg" SourcePath="Assets\Banner.jpg"/>
|
<ROW Name="Banner.jpg" SourcePath="Assets\Banner.jpg"/>
|
||||||
|
<ROW Name="ResourceCleaner.dll" SourcePath="<AI_CUSTACTS>ResourceCleaner.dll"/>
|
||||||
<ROW Name="Tabloid.jpg" SourcePath="Assets\Tabloid.jpg"/>
|
<ROW Name="Tabloid.jpg" SourcePath="Assets\Tabloid.jpg"/>
|
||||||
<ROW Name="TxtUpdater.dll" SourcePath="<AI_CUSTACTS>TxtUpdater.dll"/>
|
<ROW Name="TxtUpdater.dll" SourcePath="<AI_CUSTACTS>TxtUpdater.dll"/>
|
||||||
<ROW Name="aicustact.dll" SourcePath="<AI_CUSTACTS>aicustact.dll"/>
|
<ROW Name="aicustact.dll" SourcePath="<AI_CUSTACTS>aicustact.dll"/>
|
||||||
@ -351,7 +356,6 @@
|
|||||||
<ROW Dialog_="FatalError" Control="Title" Type="Text" X="132" Y="10" Width="220" Height="47" Attributes="196611" Text="The [ProductName] [Wizard] ended prematurely" TextStyle="VerdanaBold13" Order="800" TextLocId="Control.Text.FatalError#Title" MsiKey="FatalError#Title"/>
|
<ROW Dialog_="FatalError" Control="Title" Type="Text" X="132" Y="10" Width="220" Height="47" Attributes="196611" Text="The [ProductName] [Wizard] ended prematurely" TextStyle="VerdanaBold13" Order="800" TextLocId="Control.Text.FatalError#Title" MsiKey="FatalError#Title"/>
|
||||||
<ROW Dialog_="FilesInUse" Control="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" Attributes="1048577" Text="[BannerBitmap]" Order="400" MsiKey="FilesInUse#BannerBitmap"/>
|
<ROW Dialog_="FilesInUse" Control="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" Attributes="1048577" Text="[BannerBitmap]" Order="400" MsiKey="FilesInUse#BannerBitmap"/>
|
||||||
<ROW Dialog_="FilesInUse" Control="Logo" Type="Text" X="4" Y="228" Width="37" Height="12" Attributes="1" Text="Symphony" Order="600" TextLocId="Control.Text.FilesInUse#Logo" MsiKey="FilesInUse#Logo"/>
|
<ROW Dialog_="FilesInUse" Control="Logo" Type="Text" X="4" Y="228" Width="37" Height="12" Attributes="1" Text="Symphony" Order="600" TextLocId="Control.Text.FilesInUse#Logo" MsiKey="FilesInUse#Logo"/>
|
||||||
<ROW Dialog_="FolderDlg" Control="FolderDlgDialogInitializer" Type="DialogInitializer" X="0" Y="0" Width="0" Height="0" Attributes="0" Order="-1" TextLocId="-" HelpLocId="-" ExtDataLocId="-"/>
|
|
||||||
<ROW Dialog_="FolderDlg" Control="FolderLabel" Type="Text" X="20" Y="92" Width="348" Height="12" Attributes="3" Text="&Folder:" Help="|" Order="200" TextLocId="Control.Text.FolderDlg#FolderLabel" HelpLocId="Control.Help.FolderDlg#FolderLabel" MsiKey="FolderDlg#FolderLabel"/>
|
<ROW Dialog_="FolderDlg" Control="FolderLabel" Type="Text" X="20" Y="92" Width="348" Height="12" Attributes="3" Text="&Folder:" Help="|" Order="200" TextLocId="Control.Text.FolderDlg#FolderLabel" HelpLocId="Control.Help.FolderDlg#FolderLabel" MsiKey="FolderDlg#FolderLabel"/>
|
||||||
<ROW Dialog_="FolderDlg" Control="FolderEdit" Type="PathEdit" X="18" Y="104" Width="252" Height="18" Attributes="7" Property="APPDIR" Help="|" Order="300" HelpLocId="Control.Help.FolderDlg#FolderEdit" MsiKey="FolderDlg#FolderEdit"/>
|
<ROW Dialog_="FolderDlg" Control="FolderEdit" Type="PathEdit" X="18" Y="104" Width="252" Height="18" Attributes="7" Property="APPDIR" Help="|" Order="300" HelpLocId="Control.Help.FolderDlg#FolderEdit" MsiKey="FolderDlg#FolderEdit"/>
|
||||||
<ROW Dialog_="FolderDlg" Control="Browse" Type="PushButton" X="276" Y="104" Width="90" Height="18" Attributes="3" Text="[ButtonText_Browse]" Help="|" Order="400" TextLocId="-" HelpLocId="Control.Help.FolderDlg#Browse" MsiKey="FolderDlg#Browse"/>
|
<ROW Dialog_="FolderDlg" Control="Browse" Type="PushButton" X="276" Y="104" Width="90" Height="18" Attributes="3" Text="[ButtonText_Browse]" Help="|" Order="400" TextLocId="-" HelpLocId="Control.Help.FolderDlg#Browse" MsiKey="FolderDlg#Browse"/>
|
||||||
@ -367,6 +371,7 @@
|
|||||||
<ROW Dialog_="FolderDlg" Control="MinimizeOnCloseCheckBox" Type="CheckBox" X="20" Y="199" Width="98" Height="13" Attributes="3" Property="MINIMIZE_ON_CLOSE" Text="Minimize On Close" Order="1500"/>
|
<ROW Dialog_="FolderDlg" Control="MinimizeOnCloseCheckBox" Type="CheckBox" X="20" Y="199" Width="98" Height="13" Attributes="3" Property="MINIMIZE_ON_CLOSE" Text="Minimize On Close" Order="1500"/>
|
||||||
<ROW Dialog_="FolderDlg" Control="LaunchOnStartupCheckBox" Type="CheckBox" X="172" Y="174" Width="98" Height="13" Attributes="3" Property="AUTO_START" Text="Launch On Startup" Order="1600"/>
|
<ROW Dialog_="FolderDlg" Control="LaunchOnStartupCheckBox" Type="CheckBox" X="172" Y="174" Width="98" Height="13" Attributes="3" Property="AUTO_START" Text="Launch On Startup" Order="1600"/>
|
||||||
<ROW Dialog_="FolderDlg" Control="AlwaysOnTopCheckBox" Type="CheckBox" X="20" Y="174" Width="98" Height="13" Attributes="3" Property="ALWAYS_ON_TOP" Text="Always On Top" Order="1700"/>
|
<ROW Dialog_="FolderDlg" Control="AlwaysOnTopCheckBox" Type="CheckBox" X="20" Y="174" Width="98" Height="13" Attributes="3" Property="ALWAYS_ON_TOP" Text="Always On Top" Order="1700"/>
|
||||||
|
<ROW Dialog_="FolderDlg" Control="Edit_1" Type="Edit" X="360" Y="143" Width="2" Height="9" Attributes="2" Property="INVALID_POD_URL" Text="{260}" Order="1800"/>
|
||||||
<ROW Dialog_="InstallTypeDlg" Control="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" Attributes="1048576" Text="[DialogBitmap]" Order="100" MsiKey="InstallTypeDlg#BannerBitmap"/>
|
<ROW Dialog_="InstallTypeDlg" Control="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" Attributes="1048576" Text="[DialogBitmap]" Order="100" MsiKey="InstallTypeDlg#BannerBitmap"/>
|
||||||
<ROW Dialog_="InstallTypeDlg" Control="Bitmap_background" Type="Bitmap" X="0" Y="0" Width="370" Height="234" Attributes="1" Text="[DialogBitmap]" Order="200"/>
|
<ROW Dialog_="InstallTypeDlg" Control="Bitmap_background" Type="Bitmap" X="0" Y="0" Width="370" Height="234" Attributes="1" Text="[DialogBitmap]" Order="200"/>
|
||||||
<ROW Dialog_="InstallTypeDlg" Control="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Attributes="3" Text="[ButtonText_Next]" Order="300" TextLocId="-" MsiKey="InstallTypeDlg#Next" Options="1"/>
|
<ROW Dialog_="InstallTypeDlg" Control="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Attributes="3" Text="[ButtonText_Next]" Order="300" TextLocId="-" MsiKey="InstallTypeDlg#Next" Options="1"/>
|
||||||
@ -417,7 +422,30 @@
|
|||||||
<ROW Dialog_="ProgressDlg" Control="ProgressBar" Type="ProgressBar" X="35" Y="115" Width="300" Height="10" Attributes="65537" Text="Progress done" Order="1100" TextLocId="Control.Text.ProgressDlg#ProgressBar" MsiKey="ProgressDlg#ProgressBar"/>
|
<ROW Dialog_="ProgressDlg" Control="ProgressBar" Type="ProgressBar" X="35" Y="115" Width="300" Height="10" Attributes="65537" Text="Progress done" Order="1100" TextLocId="Control.Text.ProgressDlg#ProgressBar" MsiKey="ProgressDlg#ProgressBar"/>
|
||||||
<ROW Dialog_="ResumeDlg" Control="Title" Type="Text" X="132" Y="10" Width="220" Height="47" Attributes="196611" Text="Resuming the [ProductName] [Wizard]" TextStyle="VerdanaBold13" Order="500" TextLocId="Control.Text.ResumeDlg#Title" MsiKey="ResumeDlg#Title"/>
|
<ROW Dialog_="ResumeDlg" Control="Title" Type="Text" X="132" Y="10" Width="220" Height="47" Attributes="196611" Text="Resuming the [ProductName] [Wizard]" TextStyle="VerdanaBold13" Order="500" TextLocId="Control.Text.ResumeDlg#Title" MsiKey="ResumeDlg#Title"/>
|
||||||
<ROW Dialog_="ResumeDlg" Control="Description" Type="Text" X="132" Y="61" Width="220" Height="40" Attributes="196611" Text="The [Wizard] will complete the installation of [ProductName] on your computer. Click "Install" to continue or "Cancel" to exit the [Wizard]." Order="600" TextLocId="Control.Text.ResumeDlg#Description" MsiKey="ResumeDlg#Description"/>
|
<ROW Dialog_="ResumeDlg" Control="Description" Type="Text" X="132" Y="61" Width="220" Height="40" Attributes="196611" Text="The [Wizard] will complete the installation of [ProductName] on your computer. Click "Install" to continue or "Cancel" to exit the [Wizard]." Order="600" TextLocId="Control.Text.ResumeDlg#Description" MsiKey="ResumeDlg#Description"/>
|
||||||
|
<ROW Dialog_="SpawnWaitDialog" Control="Yes" Type="PushButton" X="72" Y="57" Width="56" Height="17" Attributes="3" Text="[ButtonText_Yes]" Order="100" TextLocId="-"/>
|
||||||
|
<ROW Dialog_="SpawnWaitDialog" Control="Icon" Type="Icon" X="15" Y="15" Width="24" Height="24" Attributes="5242881" Text="[InfoIcon]" Order="200"/>
|
||||||
|
<ROW Dialog_="SpawnWaitDialog" Control="Text" Type="Text" X="48" Y="15" Width="194" Height="30" Attributes="3" Text="New Spawn(Wait) Dialog" Order="300"/>
|
||||||
|
<ROW Dialog_="SpawnWaitDialog" Control="No" Type="PushButton" X="132" Y="57" Width="56" Height="17" Attributes="3" Text="[ButtonText_No]" Order="400" TextLocId="-"/>
|
||||||
<ROW Dialog_="UserExit" Control="Title" Type="Text" X="132" Y="10" Width="220" Height="47" Attributes="196611" Text="The [ProductName] [Wizard] was interrupted" TextStyle="VerdanaBold13" Order="500" TextLocId="Control.Text.UserExit#Title" MsiKey="UserExit#Title"/>
|
<ROW Dialog_="UserExit" Control="Title" Type="Text" X="132" Y="10" Width="220" Height="47" Attributes="196611" Text="The [ProductName] [Wizard] was interrupted" TextStyle="VerdanaBold13" Order="500" TextLocId="Control.Text.UserExit#Title" MsiKey="UserExit#Title"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control="TemplateDlgDialogInitializer" Type="DialogInitializer" X="0" Y="0" Width="0" Height="0" Attributes="0" Order="-1" TextLocId="-" HelpLocId="-" ExtDataLocId="-"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Attributes="3" Text="[ButtonText_Next]" Order="100" TextLocId="-" Options="1"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Attributes="3" Text="[ButtonText_Cancel]" Order="200" TextLocId="-" Options="1"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Attributes="3" Text="[ButtonText_Back]" Order="300" TextLocId="-" Options="1"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" Attributes="1048577" Text="[BannerBitmap]" Order="400"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control="BannerLine" Type="Line" X="0" Y="44" Width="372" Height="0" Attributes="1" Order="500"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control="BottomLine" Type="Line" X="5" Y="234" Width="368" Height="0" Attributes="1" Order="600"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Attributes="196611" Text="Verify the information entered" Order="700"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control="Logo" Type="Text" X="4" Y="228" Width="70" Height="12" Attributes="1" Text="Advanced Installer" Order="800"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Attributes="196611" Text="Settings Verification" TextStyle="[DlgTitleFont]" Order="900"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control="Text_1" Type="Text" X="25" Y="88" Width="76" Height="17" Attributes="65539" Property="TEXT_1_PROP" Text="Symphony POD Url : " Order="1000"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control="Text_2" Type="Text" X="110" Y="88" Width="145" Height="17" Attributes="65539" Property="TEXT_2_PROP" Text="[POD_URL]" Order="1100"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control="Text_3" Type="Text" X="25" Y="114" Width="76" Height="13" Attributes="65539" Property="TEXT_3_PROP" Text="Always on Top : " Order="1200"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control="Text_4" Type="Text" X="110" Y="114" Width="145" Height="10" Attributes="65539" Property="ALWAYS_ON_TOP_LABEL" Text="[ALWAYS_ON_TOP_LABEL]" Order="1300"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control="Text_5" Type="Text" X="25" Y="139" Width="76" Height="13" Attributes="65539" Property="TEXT_3_PROP_1" Text="Launch on Startup : " Order="1400"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control="Text_6" Type="Text" X="110" Y="139" Width="145" Height="10" Attributes="65539" Property="AUTO_START_LABEL" Text="[AUTO_START_LABEL]" Order="1500"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control="Text_7" Type="Text" X="25" Y="164" Width="76" Height="13" Attributes="65539" Property="TEXT_3_PROP_1_1" Text="Minimize on Close : " Order="1600"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control="Text_8" Type="Text" X="110" Y="164" Width="145" Height="10" Attributes="65539" Property="MINIMIZE_ON_CLOSE_LABEL" Text="[MINIMIZE_ON_CLOSE_LABEL]" Order="1700"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control="Text_9" Type="Text" X="25" Y="67" Width="321" Height="25" Attributes="65539" Property="TEXT_9_PROP" Text="You seem to have entered an invalid pod url. Please go back to the previous screen and rectify it." Order="1800"/>
|
||||||
<ROW Dialog_="VerifyReadyDlg" Control="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" Attributes="1048577" Text="[BannerBitmap]" Order="300" MsiKey="VerifyReadyDlg#BannerBitmap"/>
|
<ROW Dialog_="VerifyReadyDlg" Control="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" Attributes="1048577" Text="[BannerBitmap]" Order="300" MsiKey="VerifyReadyDlg#BannerBitmap"/>
|
||||||
<ROW Dialog_="VerifyReadyDlg" Control="Logo" Type="Text" X="5" Y="228" Width="39" Height="12" Attributes="1" Text="Symphony" Order="500" TextLocId="Control.Text.VerifyReadyDlg#Logo" MsiKey="VerifyReadyDlg#Logo"/>
|
<ROW Dialog_="VerifyReadyDlg" Control="Logo" Type="Text" X="5" Y="228" Width="39" Height="12" Attributes="1" Text="Symphony" Order="500" TextLocId="Control.Text.VerifyReadyDlg#Logo" MsiKey="VerifyReadyDlg#Logo"/>
|
||||||
<ROW Dialog_="VerifyReadyDlg" Control="Text" Type="Text" X="25" Y="70" Width="320" Height="21" Attributes="196611" Text="Click "Install" to begin the installation. If you want to review or change any of your installation settings, click "Back". Click "Cancel" to exit the wizard." Order="700" TextLocId="Control.Text.VerifyReadyDlg#Text" MsiKey="VerifyReadyDlg#Text"/>
|
<ROW Dialog_="VerifyReadyDlg" Control="Text" Type="Text" X="25" Y="70" Width="320" Height="21" Attributes="196611" Text="Click "Install" to begin the installation. If you want to review or change any of your installation settings, click "Back". Click "Cancel" to exit the wizard." Order="700" TextLocId="Control.Text.VerifyReadyDlg#Text" MsiKey="VerifyReadyDlg#Text"/>
|
||||||
@ -430,6 +458,16 @@
|
|||||||
<ATTRIBUTE name="DeletedRows" value="ExitDialog#ViewReadmeText@FolderDlg#Logo@InstallTypeDlg#BannerLine@InstallTypeDlg#InstallTypeText@InstallTypeDlg#Logo@InstallTypeDlg#Title@ProgressDlg#Logo@InstallTypeDlg#Description"/>
|
<ATTRIBUTE name="DeletedRows" value="ExitDialog#ViewReadmeText@FolderDlg#Logo@InstallTypeDlg#BannerLine@InstallTypeDlg#InstallTypeText@InstallTypeDlg#Logo@InstallTypeDlg#Title@ProgressDlg#Logo@InstallTypeDlg#Description"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiControlConditionComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiControlConditionComponent">
|
||||||
|
<ROW Dialog_="VerifyDlg" Control_="Next" Action="Disable" Condition="INVALID_POD_URL = "invalid""/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control_="Text_1" Action="Hide" Condition="INVALID_POD_URL = "invalid""/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control_="Text_2" Action="Hide" Condition="INVALID_POD_URL = "invalid""/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control_="Text_3" Action="Hide" Condition="INVALID_POD_URL = "invalid""/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control_="Text_4" Action="Hide" Condition="INVALID_POD_URL = "invalid""/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control_="Text_5" Action="Hide" Condition="INVALID_POD_URL = "invalid""/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control_="Text_6" Action="Hide" Condition="INVALID_POD_URL = "invalid""/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control_="Text_7" Action="Hide" Condition="INVALID_POD_URL = "invalid""/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control_="Text_8" Action="Hide" Condition="INVALID_POD_URL = "invalid""/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control_="Text_9" Action="Hide" Condition="INVALID_POD_URL = "valid""/>
|
||||||
<ATTRIBUTE name="DeletedRows" value="ExitDialog#ViewReadmeText#Hide#((NOT AI_INSTALL) AND (NOT AI_PATCH)) OR ((CTRLS <> 1) AND (CTRLS <> 3))"/>
|
<ATTRIBUTE name="DeletedRows" value="ExitDialog#ViewReadmeText#Hide#((NOT AI_INSTALL) AND (NOT AI_PATCH)) OR ((CTRLS <> 1) AND (CTRLS <> 3))"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiControlEventComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiControlEventComponent">
|
||||||
@ -451,23 +489,35 @@
|
|||||||
<ROW Dialog_="VerifyReadyDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_PATCH" Ordering="199"/>
|
<ROW Dialog_="VerifyReadyDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_PATCH" Ordering="199"/>
|
||||||
<ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="PatchWelcomeDlg" Condition="AI_PATCH" Ordering="203"/>
|
<ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="PatchWelcomeDlg" Condition="AI_PATCH" Ordering="203"/>
|
||||||
<ROW Dialog_="InstallTypeDlg" Control_="Next" Event="NewDialog" Argument="FolderDlg" Condition="AI_INSTALL" Ordering="101"/>
|
<ROW Dialog_="InstallTypeDlg" Control_="Next" Event="NewDialog" Argument="FolderDlg" Condition="AI_INSTALL" Ordering="101"/>
|
||||||
<ROW Dialog_="FolderDlg" Control_="Next" Event="EndDialog" Argument="Return" Condition="AI_INSTALL" Ordering="201"/>
|
<ROW Dialog_="FolderDlg" Control_="Next" Event="NewDialog" Argument="VerifyDlg" Condition="AI_INSTALL" Ordering="201"/>
|
||||||
<ROW Dialog_="FolderDlg" Control_="Back" Event="NewDialog" Argument="InstallTypeDlg" Condition="AI_INSTALL" Ordering="1"/>
|
<ROW Dialog_="FolderDlg" Control_="Back" Event="NewDialog" Argument="InstallTypeDlg" Condition="AI_INSTALL" Ordering="1"/>
|
||||||
<ROW Dialog_="FolderDlg" Control_="Next" Event="SpawnDialog" Argument="OutOfRbDiskDlg" Condition="AI_INSTALL AND OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)" Ordering="202" Options="2"/>
|
<ROW Dialog_="FolderDlg" Control_="Next" Event="DoAction" Argument="PodUrlValidation" Condition="AI_INSTALL" Ordering="215"/>
|
||||||
<ROW Dialog_="FolderDlg" Control_="Next" Event="EnableRollback" Argument="False" Condition="AI_INSTALL AND OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"" Ordering="203" Options="2"/>
|
<ROW Dialog_="SpawnWaitDialog" Control_="No" Event="EndDialog" Argument="Return" Condition="1" Ordering="100"/>
|
||||||
<ROW Dialog_="FolderDlg" Control_="Next" Event="SpawnDialog" Argument="OutOfDiskDlg" Condition="AI_INSTALL AND ( (OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F") )" Ordering="204" Options="2"/>
|
<ROW Dialog_="SpawnWaitDialog" Control_="Yes" Event="EndDialog" Argument="Return" Condition="1" Ordering="100"/>
|
||||||
<ROW Dialog_="FolderDlg" Control_="FolderDlgDialogInitializer" Event="[AI_ButtonText_Next_Orig]" Argument="[ButtonText_Next]" Condition="AI_INSTALL" Ordering="0" Options="2"/>
|
<ROW Dialog_="VerifyDlg" Control_="Cancel" Event="SpawnDialog" Argument="CancelDlg" Condition="1" Ordering="100"/>
|
||||||
<ROW Dialog_="FolderDlg" Control_="FolderDlgDialogInitializer" Event="[ButtonText_Next]" Argument="[[AI_CommitButton]]" Condition="AI_INSTALL" Ordering="1" Options="2"/>
|
<ROW Dialog_="VerifyDlg" Control_="Next" Event="EndDialog" Argument="Return" Condition="AI_INSTALL" Ordering="1"/>
|
||||||
<ROW Dialog_="FolderDlg" Control_="FolderDlgDialogInitializer" Event="[AI_Text_Next_Orig]" Argument="[Text_Next]" Condition="AI_INSTALL" Ordering="2" Options="2"/>
|
<ROW Dialog_="VerifyDlg" Control_="Back" Event="NewDialog" Argument="FolderDlg" Condition="AI_INSTALL" Ordering="1"/>
|
||||||
<ROW Dialog_="FolderDlg" Control_="FolderDlgDialogInitializer" Event="[Text_Next]" Argument="[Text_Install]" Condition="AI_INSTALL" Ordering="3" Options="2"/>
|
<ROW Dialog_="VerifyDlg" Control_="Next" Event="SpawnDialog" Argument="OutOfRbDiskDlg" Condition="AI_INSTALL AND OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)" Ordering="2" Options="2"/>
|
||||||
<ROW Dialog_="FolderDlg" Control_="Back" Event="[ButtonText_Next]" Argument="[AI_ButtonText_Next_Orig]" Condition="AI_INSTALL" Ordering="2" Options="2"/>
|
<ROW Dialog_="VerifyDlg" Control_="Next" Event="EnableRollback" Argument="False" Condition="AI_INSTALL AND OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"" Ordering="3" Options="2"/>
|
||||||
<ROW Dialog_="FolderDlg" Control_="Back" Event="[Text_Next]" Argument="[AI_Text_Next_Orig]" Condition="AI_INSTALL" Ordering="3" Options="2"/>
|
<ROW Dialog_="VerifyDlg" Control_="Next" Event="SpawnDialog" Argument="OutOfDiskDlg" Condition="AI_INSTALL AND ( (OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F") )" Ordering="4" Options="2"/>
|
||||||
<ROW Dialog_="FolderDlg" Control_="Next" Event="DoAction" Argument="CheckBoxesScript" Condition="AI_INSTALL" Ordering="205"/>
|
<ROW Dialog_="VerifyDlg" Control_="TemplateDlgDialogInitializer" Event="[AI_ButtonText_Next_Orig]" Argument="[ButtonText_Next]" Condition="AI_INSTALL" Ordering="0" Options="2"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control_="TemplateDlgDialogInitializer" Event="[ButtonText_Next]" Argument="[[AI_CommitButton]]" Condition="AI_INSTALL" Ordering="1" Options="2"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control_="TemplateDlgDialogInitializer" Event="[AI_Text_Next_Orig]" Argument="[Text_Next]" Condition="AI_INSTALL" Ordering="2" Options="2"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control_="TemplateDlgDialogInitializer" Event="[Text_Next]" Argument="[Text_Install]" Condition="AI_INSTALL" Ordering="3" Options="2"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control_="Back" Event="[ButtonText_Next]" Argument="[AI_ButtonText_Next_Orig]" Condition="AI_INSTALL" Ordering="2" Options="2"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control_="Back" Event="[Text_Next]" Argument="[AI_Text_Next_Orig]" Condition="AI_INSTALL" Ordering="3" Options="2"/>
|
||||||
|
<ROW Dialog_="VerifyDlg" Control_="Next" Event="DoAction" Argument="SetCheckboxValues" Condition="AI_INSTALL" Ordering="5"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiCreateFolderComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiCreateFolderComponent">
|
||||||
<ROW Directory_="Symphony_Dir" Component_="Symphony" ManualDelete="false"/>
|
<ROW Directory_="Symphony_Dir" Component_="Symphony" ManualDelete="false"/>
|
||||||
|
<ROW Directory_="node_modules_Dir" Component_="node_modules" ManualDelete="false"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiCustActComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiCustActComponent">
|
||||||
|
<ROW Action="AI_AiBackupCleanup" Type="1" Source="ResourceCleaner.dll" Target="OnAiBackupCleanup" WithoutSeq="true"/>
|
||||||
|
<ROW Action="AI_AiBackupImmediate" Type="1" Source="ResourceCleaner.dll" Target="OnAiBackupImmediate"/>
|
||||||
|
<ROW Action="AI_AiBackupRollback" Type="11521" Source="ResourceCleaner.dll" Target="OnAiBackupRollback"/>
|
||||||
|
<ROW Action="AI_AiRestoreDeferred" Type="11265" Source="ResourceCleaner.dll" Target="OnAiRestoreDeferred"/>
|
||||||
|
<ROW Action="AI_AiRestoreRollback" Type="11521" Source="ResourceCleaner.dll" Target="OnAiRestoreRollback" WithoutSeq="true"/>
|
||||||
<ROW Action="AI_AuthorSinglePackage" Type="1" Source="aicustact.dll" Target="AI_AuthorSinglePackage" WithoutSeq="true"/>
|
<ROW Action="AI_AuthorSinglePackage" Type="1" Source="aicustact.dll" Target="AI_AuthorSinglePackage" WithoutSeq="true"/>
|
||||||
<ROW Action="AI_DATA_SETTER" Type="51" Source="CustomActionData" Target="Symphony.exe"/>
|
<ROW Action="AI_DATA_SETTER" Type="51" Source="CustomActionData" Target="Symphony.exe"/>
|
||||||
<ROW Action="AI_DATA_SETTER_2" Type="51" Source="CustomActionData" Target="Symphony.exe"/>
|
<ROW Action="AI_DATA_SETTER_2" Type="51" Source="CustomActionData" Target="Symphony.exe"/>
|
||||||
@ -485,21 +535,27 @@
|
|||||||
<ROW Action="AI_TxtUpdaterConfig" Type="11265" Source="TxtUpdater.dll" Target="OnTxtUpdaterConfig" WithoutSeq="true"/>
|
<ROW Action="AI_TxtUpdaterConfig" Type="11265" Source="TxtUpdater.dll" Target="OnTxtUpdaterConfig" WithoutSeq="true"/>
|
||||||
<ROW Action="AI_TxtUpdaterInstall" Type="1" Source="TxtUpdater.dll" Target="OnTxtUpdaterInstall"/>
|
<ROW Action="AI_TxtUpdaterInstall" Type="1" Source="TxtUpdater.dll" Target="OnTxtUpdaterInstall"/>
|
||||||
<ROW Action="AI_TxtUpdaterRollback" Type="11521" Source="TxtUpdater.dll" Target="OnTxtUpdaterRollback" WithoutSeq="true"/>
|
<ROW Action="AI_TxtUpdaterRollback" Type="11521" Source="TxtUpdater.dll" Target="OnTxtUpdaterRollback" WithoutSeq="true"/>
|
||||||
<ROW Action="CheckBoxesScript" Type="37" Target="Session.Property("MIN_ON_CLOSE_PROP") = (Session.Property("MIN_ON_CLOSE") === "Checkbox" ? "true" : "false");" TargetUnformatted="Session.Property("AUTO_START") = (Session.Property("AUTO_START") === "true" ? "true" : "false"); Session.Property("MINIMIZE_ON_CLOSE") = (Session.Property("MINIMIZE_ON_CLOSE") === "true" ? "true" : "false"); Session.Property("ALWAYS_ON_TOP") = (Session.Property("ALWAYS_ON_TOP") === "true" ? "true" : "false");" WithoutSeq="true"/>
|
|
||||||
<ROW Action="KillParagon" Type="1" Source="aicustact.dll" Target="StopProcess" Options="1" AdditionalSeq="AI_DATA_SETTER_2"/>
|
<ROW Action="KillParagon" Type="1" Source="aicustact.dll" Target="StopProcess" Options="1" AdditionalSeq="AI_DATA_SETTER_2"/>
|
||||||
<ROW Action="KillRenderer" Type="1" Source="aicustact.dll" Target="StopProcess" Options="1" AdditionalSeq="AI_DATA_SETTER"/>
|
<ROW Action="KillRenderer" Type="1" Source="aicustact.dll" Target="StopProcess" Options="1" AdditionalSeq="AI_DATA_SETTER"/>
|
||||||
|
<ROW Action="PodUrlValidation" Type="37" Target="Script Text" TargetUnformatted="// First, check if the protocol is part of the url, if not, prepend it var prefix = "https://"; if (Session.Property("POD_URL").substr(0, prefix.length) !== prefix) { 	Session.Property("POD_URL") = prefix + Session.Property("POD_URL"); } // Check if the entered pod url is valid var podUrlRE = /^((?:http:\/\/)|(?:https:\/\/))(www.)?((?:[a-zA-Z0-9]+\.[a-z]{3})|(?:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?::\d+)?))([\/a-zA-Z0-9\.]*)$/; var podUrlTest = podUrlRE.test(Session.Property("POD_URL")); if (!podUrlTest) { 	Session.Property("INVALID_POD_URL") = "invalid"; } else { 	Session.Property("INVALID_POD_URL") = "valid"; } // By default, we set all the values to false and change based on conditions Session.Property("ALWAYS_ON_TOP_LABEL") = "false"; Session.Property("AUTO_START_LABEL") = "false"; Session.Property("MINIMIZE_ON_CLOSE_LABEL") = "false"; // If always on top is checked in the checkbox, set the label value to true if (Session.Property("ALWAYS_ON_TOP") && Session.Property("ALWAYS_ON_TOP") === "true") { Session.Property("ALWAYS_ON_TOP_LABEL") = "true"; } // If launch on startup is checked in the checkbox, set the label value to true if (Session.Property("MINIMIZE_ON_CLOSE") && Session.Property("MINIMIZE_ON_CLOSE") === "true") { Session.Property("MINIMIZE_ON_CLOSE_LABEL") = "true"; } // If minimise on close is checked in the checkbox, set the label value to true if (Session.Property("AUTO_START") && Session.Property("AUTO_START") === "true") { Session.Property("AUTO_START_LABEL") = "true"; }" WithoutSeq="true"/>
|
||||||
<ROW Action="SET_APPDIR" Type="307" Source="APPDIR" Target="[ProgramFilesFolder][Manufacturer]\[ProductName]" MultiBuildTarget="DefaultBuild:[AI_UserProgramFiles][Manufacturer]\[ProductName]"/>
|
<ROW Action="SET_APPDIR" Type="307" Source="APPDIR" Target="[ProgramFilesFolder][Manufacturer]\[ProductName]" MultiBuildTarget="DefaultBuild:[AI_UserProgramFiles][Manufacturer]\[ProductName]"/>
|
||||||
<ROW Action="SET_SHORTCUTDIR" Type="307" Source="SHORTCUTDIR" Target="[ProgramMenuFolder][ProductName]"/>
|
<ROW Action="SET_SHORTCUTDIR" Type="307" Source="SHORTCUTDIR" Target="[ProgramMenuFolder][ProductName]"/>
|
||||||
<ROW Action="SET_TARGETDIR_TO_APPDIR" Type="51" Source="TARGETDIR" Target="[APPDIR]"/>
|
<ROW Action="SET_TARGETDIR_TO_APPDIR" Type="51" Source="TARGETDIR" Target="[APPDIR]"/>
|
||||||
<ROW Action="Symphony.exe" Type="1042" Source="Symphony.exe" Target="--install"/>
|
<ROW Action="SetCheckboxValues" Type="37" Target="Script Text" TargetUnformatted="// Pick the values from the selected checkboxes and set it against the session variables Session.Property("AUTO_START") = (Session.Property("AUTO_START") === "true" ? "true" : "false"); Session.Property("MINIMIZE_ON_CLOSE") = (Session.Property("MINIMIZE_ON_CLOSE") === "true" ? "true" : "false"); Session.Property("ALWAYS_ON_TOP") = (Session.Property("ALWAYS_ON_TOP") === "true" ? "true" : "false");" WithoutSeq="true"/>
|
||||||
|
<ROW Action="Symphony.exe" Type="1042" Source="Symphony.exe" Target="--install --peruser"/>
|
||||||
|
<ROW Action="Symphony.exe_All_User" Type="1042" Source="Symphony.exe" Target="--install"/>
|
||||||
<ROW Action="UninstallPreviousVersions" Type="1" Source="aicustact.dll" Target="UninstallPreviousVersions" Options="1"/>
|
<ROW Action="UninstallPreviousVersions" Type="1" Source="aicustact.dll" Target="UninstallPreviousVersions" Options="1"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiDialogComponent">
|
||||||
|
<ROW Dialog="SpawnWaitDialog" HCentering="50" VCentering="50" Width="260" Height="85" Attributes="3" Title="[ProductName] [Setup]" Control_Default="Yes" Control_Cancel="No"/>
|
||||||
|
<ROW Dialog="VerifyDlg" HCentering="50" VCentering="50" Width="370" Height="270" Attributes="3" Title="[ProductName] [Setup]" Control_Default="Next" Control_Cancel="Cancel"/>
|
||||||
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiIconsComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiIconsComponent">
|
||||||
<ROW Name="icon.exe" SourcePath="..\..\build\icon.ico" Index="0"/>
|
<ROW Name="icon.exe" SourcePath="..\..\build\icon.ico" Index="0"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstExSeqComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstExSeqComponent">
|
||||||
<ROW Action="AI_DOWNGRADE" Condition="AI_NEWERPRODUCTFOUND AND (UILevel <> 5)" Sequence="210"/>
|
<ROW Action="AI_DOWNGRADE" Condition="AI_NEWERPRODUCTFOUND AND (UILevel <> 5)" Sequence="210"/>
|
||||||
<ROW Action="AI_STORE_LOCATION" Condition="(Not Installed) OR REINSTALL" Sequence="1501"/>
|
<ROW Action="AI_STORE_LOCATION" Condition="(Not Installed) OR REINSTALL" Sequence="1502"/>
|
||||||
<ROW Action="AI_PREPARE_UPGRADE" Condition="AI_UPGRADE="No" AND (Not Installed)" Sequence="1399"/>
|
<ROW Action="AI_PREPARE_UPGRADE" Condition="AI_UPGRADE="No" AND (Not Installed)" Sequence="1399"/>
|
||||||
<ROW Action="AI_ResolveKnownFolders" Sequence="53"/>
|
<ROW Action="AI_ResolveKnownFolders" Sequence="53"/>
|
||||||
<ROW Action="AI_GetArpIconPath" Sequence="1401"/>
|
<ROW Action="AI_GetArpIconPath" Sequence="1401"/>
|
||||||
@ -509,7 +565,11 @@
|
|||||||
<ROW Action="AI_DATA_SETTER" Sequence="54"/>
|
<ROW Action="AI_DATA_SETTER" Sequence="54"/>
|
||||||
<ROW Action="AI_SETMIXINSTLOCATION" Sequence="749"/>
|
<ROW Action="AI_SETMIXINSTLOCATION" Sequence="749"/>
|
||||||
<ROW Action="AI_TxtUpdaterInstall" Sequence="5101"/>
|
<ROW Action="AI_TxtUpdaterInstall" Sequence="5101"/>
|
||||||
<ROW Action="Symphony.exe" Condition="( NOT Installed )" Sequence="5935"/>
|
<ROW Action="Symphony.exe" Condition="( NOT Installed ) AND ( MSIINSTALLPERUSER )" Sequence="5935"/>
|
||||||
|
<ROW Action="Symphony.exe_All_User" Condition="( NOT Installed ) AND ( ALLUSERS )" Sequence="5936"/>
|
||||||
|
<ROW Action="AI_AiBackupImmediate" Sequence="1001"/>
|
||||||
|
<ROW Action="AI_AiBackupRollback" Sequence="1501"/>
|
||||||
|
<ROW Action="AI_AiRestoreDeferred" Sequence="6599"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstallUISequenceComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstallUISequenceComponent">
|
||||||
<ROW Action="AI_ResolveKnownFolders" Sequence="52"/>
|
<ROW Action="AI_ResolveKnownFolders" Sequence="52"/>
|
||||||
@ -540,6 +600,7 @@
|
|||||||
<ROW Registry="HelpTelephone" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="HelpTelephone" Value="[ARPHELPTELEPHONE]" Component_="AI_CustomARPName"/>
|
<ROW Registry="HelpTelephone" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="HelpTelephone" Value="[ARPHELPTELEPHONE]" Component_="AI_CustomARPName"/>
|
||||||
<ROW Registry="InstallLocation" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="InstallLocation" Value="[APPDIR]" Component_="AI_CustomARPName"/>
|
<ROW Registry="InstallLocation" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="InstallLocation" Value="[APPDIR]" Component_="AI_CustomARPName"/>
|
||||||
<ROW Registry="ModifyPath" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="ModifyPath" Value="[AI_UNINSTALLER] /I [ProductCode]" Component_="AI_CustomARPName"/>
|
<ROW Registry="ModifyPath" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="ModifyPath" Value="[AI_UNINSTALLER] /I [ProductCode]" Component_="AI_CustomARPName"/>
|
||||||
|
<ROW Registry="NoModify" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="NoModify" Value="#1" Component_="AI_DisableModify"/>
|
||||||
<ROW Registry="NoRepair" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="NoRepair" Value="#1" Component_="AI_CustomARPName"/>
|
<ROW Registry="NoRepair" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="NoRepair" Value="#1" Component_="AI_CustomARPName"/>
|
||||||
<ROW Registry="Path" Root="-1" Key="Software\[Manufacturer]\[ProductName]" Name="Path" Value="[APPDIR]" Component_="ProductInformation"/>
|
<ROW Registry="Path" Root="-1" Key="Software\[Manufacturer]\[ProductName]" Name="Path" Value="[APPDIR]" Component_="ProductInformation"/>
|
||||||
<ROW Registry="PodUrl" Root="-1" Key="Software\[Manufacturer]\[ProductName]" Name="PodUrl" Component_="PodUrl"/>
|
<ROW Registry="PodUrl" Root="-1" Key="Software\[Manufacturer]\[ProductName]" Name="PodUrl" Component_="PodUrl"/>
|
||||||
|
52
js/aboutApp/about-app.html
Normal file
52
js/aboutApp/about-app.html
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>About Symphony</title>
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
margin: 0;
|
||||||
|
height: 100%;
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
.name {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 1.3em;
|
||||||
|
padding: 10px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.version-text {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 1em;
|
||||||
|
color: #2f2f2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright-text {
|
||||||
|
flex: 1;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 0.6em;
|
||||||
|
color: #7f7f7f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding-top: 20px
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="content">
|
||||||
|
<img class="logo" src="symphony-logo.png">
|
||||||
|
<span id="app-name" class="name">Symphony</span>
|
||||||
|
<span id="version" class="version-text"></span>
|
||||||
|
<span id="copyright" class="copyright-text"></span>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
105
js/aboutApp/index.js
Normal file
105
js/aboutApp/index.js
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const electron = require('electron');
|
||||||
|
const BrowserWindow = electron.BrowserWindow;
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
const log = require('../log.js');
|
||||||
|
const logLevels = require('../enums/logLevels.js');
|
||||||
|
const buildNumber = require('../../package.json').buildNumber;
|
||||||
|
|
||||||
|
let aboutWindow;
|
||||||
|
|
||||||
|
let windowConfig = {
|
||||||
|
width: 350,
|
||||||
|
height: 260,
|
||||||
|
show: false,
|
||||||
|
modal: true,
|
||||||
|
autoHideMenuBar: true,
|
||||||
|
titleBarStyle: true,
|
||||||
|
resizable: false,
|
||||||
|
webPreferences: {
|
||||||
|
preload: path.join(__dirname, 'renderer.js'),
|
||||||
|
sandbox: true,
|
||||||
|
nodeIntegration: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* method to get the HTML template path
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function getTemplatePath() {
|
||||||
|
let templatePath = path.join(__dirname, 'about-app.html');
|
||||||
|
try {
|
||||||
|
fs.statSync(templatePath).isFile();
|
||||||
|
} catch (err) {
|
||||||
|
log.send(logLevels.ERROR, 'about-window: Could not find template ("' + templatePath + '").');
|
||||||
|
}
|
||||||
|
return 'file://' + templatePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the about application window for a specific window
|
||||||
|
* @param {String} windowName - name of the window upon
|
||||||
|
* which this window should show
|
||||||
|
*/
|
||||||
|
function openAboutWindow(windowName) {
|
||||||
|
|
||||||
|
// This prevents creating multiple instances of the
|
||||||
|
// about window
|
||||||
|
if (aboutWindow) {
|
||||||
|
if (aboutWindow.isMinimized()) {
|
||||||
|
aboutWindow.restore();
|
||||||
|
}
|
||||||
|
aboutWindow.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let allWindows = BrowserWindow.getAllWindows();
|
||||||
|
allWindows = allWindows.find((window) => { return window.winName === windowName });
|
||||||
|
|
||||||
|
// if we couldn't find any window matching the window name
|
||||||
|
// it will render as a new window
|
||||||
|
if (allWindows) {
|
||||||
|
windowConfig.parent = allWindows;
|
||||||
|
}
|
||||||
|
|
||||||
|
aboutWindow = new BrowserWindow(windowConfig);
|
||||||
|
aboutWindow.setVisibleOnAllWorkspaces(true);
|
||||||
|
aboutWindow.loadURL(getTemplatePath());
|
||||||
|
|
||||||
|
// sets the AlwaysOnTop property for the about window
|
||||||
|
// if the main window's AlwaysOnTop is true
|
||||||
|
let focusedWindow = BrowserWindow.getFocusedWindow();
|
||||||
|
if (focusedWindow && focusedWindow.isAlwaysOnTop()) {
|
||||||
|
aboutWindow.setAlwaysOnTop(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
aboutWindow.once('ready-to-show', () => {
|
||||||
|
aboutWindow.show();
|
||||||
|
});
|
||||||
|
|
||||||
|
aboutWindow.webContents.on('did-finish-load', () => {
|
||||||
|
aboutWindow.webContents.send('buildNumber', buildNumber || '0');
|
||||||
|
});
|
||||||
|
|
||||||
|
aboutWindow.on('close', () => {
|
||||||
|
destroyWindow();
|
||||||
|
});
|
||||||
|
|
||||||
|
aboutWindow.on('closed', () => {
|
||||||
|
destroyWindow();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys a window
|
||||||
|
*/
|
||||||
|
function destroyWindow() {
|
||||||
|
aboutWindow = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
openAboutWindow: openAboutWindow
|
||||||
|
};
|
27
js/aboutApp/renderer.js
Normal file
27
js/aboutApp/renderer.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
'use strict';
|
||||||
|
const { remote, ipcRenderer } = require('electron');
|
||||||
|
|
||||||
|
renderDom();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that renders application data
|
||||||
|
*/
|
||||||
|
function renderDom() {
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
const applicationName = remote.app.getName() || 'Symphony';
|
||||||
|
let appName = document.getElementById('app-name');
|
||||||
|
let copyright = document.getElementById('copyright');
|
||||||
|
|
||||||
|
appName.innerHTML = applicationName;
|
||||||
|
copyright.innerHTML = `Copyright © ${new Date().getFullYear()} ${applicationName}`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ipcRenderer.on('buildNumber', (event, buildNumber) => {
|
||||||
|
let versionText = document.getElementById('version');
|
||||||
|
const version = remote.app.getVersion();
|
||||||
|
|
||||||
|
if (versionText) {
|
||||||
|
versionText.innerHTML = version ? `Version ${version} (${version}.${buildNumber})` : 'N/A';
|
||||||
|
}
|
||||||
|
});
|
BIN
js/aboutApp/symphony-logo.png
Normal file
BIN
js/aboutApp/symphony-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.1 KiB |
@ -16,7 +16,7 @@ let throttleActivity;
|
|||||||
function activityDetection() {
|
function activityDetection() {
|
||||||
// Get system idle status and idle time from PaulCBetts package
|
// Get system idle status and idle time from PaulCBetts package
|
||||||
if (systemIdleTime.getIdleTime() < maxIdleTime) {
|
if (systemIdleTime.getIdleTime() < maxIdleTime) {
|
||||||
return {isUserIdle: false, systemIdleTime: systemIdleTime.getIdleTime()};
|
return { isUserIdle: false, systemIdleTime: systemIdleTime.getIdleTime() };
|
||||||
}
|
}
|
||||||
|
|
||||||
// If idle for more than 4 mins, monitor system idle status every second
|
// If idle for more than 4 mins, monitor system idle status every second
|
||||||
@ -65,7 +65,7 @@ function monitorUserActivity() {
|
|||||||
function sendActivity() {
|
function sendActivity() {
|
||||||
let systemActivity = activityDetection();
|
let systemActivity = activityDetection();
|
||||||
if (systemActivity && !systemActivity.isUserIdle && systemActivity.systemIdleTime) {
|
if (systemActivity && !systemActivity.isUserIdle && systemActivity.systemIdleTime) {
|
||||||
send({systemIdleTime: systemActivity.systemIdleTime});
|
send({ systemIdleTime: systemActivity.systemIdleTime });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,6 +84,11 @@ function send(data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the activity's window
|
||||||
|
* @param period
|
||||||
|
* @param win
|
||||||
|
*/
|
||||||
function setActivityWindow(period, win) {
|
function setActivityWindow(period, win) {
|
||||||
maxIdleTime = period;
|
maxIdleTime = period;
|
||||||
activityWindow = win;
|
activityWindow = win;
|
||||||
@ -95,6 +100,5 @@ module.exports = {
|
|||||||
send: send,
|
send: send,
|
||||||
setActivityWindow: setActivityWindow,
|
setActivityWindow: setActivityWindow,
|
||||||
activityDetection: activityDetection,
|
activityDetection: activityDetection,
|
||||||
monitorUserActivity: monitorUserActivity, // Exporting this for unit test
|
monitorUserActivity: monitorUserActivity, // Exporting this for unit tests
|
||||||
initiateActivityDetection: initiateActivityDetection
|
};
|
||||||
};
|
|
@ -10,6 +10,10 @@ const maxCount = 1e8;
|
|||||||
const log = require('./log.js');
|
const log = require('./log.js');
|
||||||
const logLevels = require('./enums/logLevels.js');
|
const logLevels = require('./enums/logLevels.js');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the badge count
|
||||||
|
* @param count
|
||||||
|
*/
|
||||||
function show(count) {
|
function show(count) {
|
||||||
if (typeof count !== 'number') {
|
if (typeof count !== 'number') {
|
||||||
log.send(logLevels.WARN, 'badgeCount: invalid func arg, must be a number: ' + count);
|
log.send(logLevels.WARN, 'badgeCount: invalid func arg, must be a number: ' + count);
|
||||||
@ -37,6 +41,11 @@ function show(count) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the data url
|
||||||
|
* @param dataUrl
|
||||||
|
* @param count
|
||||||
|
*/
|
||||||
function setDataUrl(dataUrl, count) {
|
function setDataUrl(dataUrl, count) {
|
||||||
const mainWindow = windowMgr.getMainWindow();
|
const mainWindow = windowMgr.getMainWindow();
|
||||||
if (mainWindow && dataUrl && count) {
|
if (mainWindow && dataUrl && count) {
|
||||||
@ -50,4 +59,4 @@ function setDataUrl(dataUrl, count) {
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
show: show,
|
show: show,
|
||||||
setDataUrl: setDataUrl
|
setDataUrl: setDataUrl
|
||||||
}
|
};
|
||||||
|
91
js/basicAuth/basic-auth.html
Normal file
91
js/basicAuth/basic-auth.html
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Authentication Request</title>
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
margin: 0;
|
||||||
|
height: 100%;
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
padding-top: 10px;
|
||||||
|
text-align: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hostname {
|
||||||
|
font-size: .9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
padding-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-spacing: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
width: 200px;
|
||||||
|
height: 20px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
display: flex;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-container {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<span>Please provide your login credentials for:</span>
|
||||||
|
<span id="hostname" class="hostname">hostname</span>
|
||||||
|
<form id="basicAuth" name="Basic Auth" action="Login">
|
||||||
|
<table class="form">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>User name:</td>
|
||||||
|
<td>
|
||||||
|
<input id="username" name="username" title="Username" required>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Password:</td>
|
||||||
|
<td>
|
||||||
|
<input id="password" type="password" title="Password" required>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="footer">
|
||||||
|
<div class="button-container">
|
||||||
|
<button type="submit" id="login">Log In</button>
|
||||||
|
</div>
|
||||||
|
<div class="button-container">
|
||||||
|
<button id="cancel">Cancel</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
126
js/basicAuth/index.js
Normal file
126
js/basicAuth/index.js
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const electron = require('electron');
|
||||||
|
const BrowserWindow = electron.BrowserWindow;
|
||||||
|
const ipc = electron.ipcMain;
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
const log = require('../log.js');
|
||||||
|
const logLevels = require('../enums/logLevels.js');
|
||||||
|
|
||||||
|
let basicAuthWindow;
|
||||||
|
|
||||||
|
const local = {};
|
||||||
|
|
||||||
|
let windowConfig = {
|
||||||
|
width: 360,
|
||||||
|
height: 270,
|
||||||
|
show: false,
|
||||||
|
modal: true,
|
||||||
|
autoHideMenuBar: true,
|
||||||
|
titleBarStyle: true,
|
||||||
|
resizable: false,
|
||||||
|
webPreferences: {
|
||||||
|
preload: path.join(__dirname, 'renderer.js'),
|
||||||
|
sandbox: true,
|
||||||
|
nodeIntegration: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* method to get the HTML template path
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function getTemplatePath() {
|
||||||
|
let templatePath = path.join(__dirname, 'basic-auth.html');
|
||||||
|
try {
|
||||||
|
fs.statSync(templatePath).isFile();
|
||||||
|
} catch (err) {
|
||||||
|
log.send(logLevels.ERROR, 'basic-auth: Could not find template ("' + templatePath + '").');
|
||||||
|
}
|
||||||
|
return 'file://' + templatePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the basic auth window for authentication
|
||||||
|
* @param {String} windowName - name of the window upon which this window should show
|
||||||
|
* @param {String} hostname - name of the website that requires authentication
|
||||||
|
* @param {Function} callback
|
||||||
|
*/
|
||||||
|
function openBasicAuthWindow(windowName, hostname, callback) {
|
||||||
|
|
||||||
|
// Register callback function
|
||||||
|
if (typeof callback === 'function') {
|
||||||
|
local.authCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This prevents creating multiple instances of the
|
||||||
|
// basic auth window
|
||||||
|
if (basicAuthWindow) {
|
||||||
|
if (basicAuthWindow.isMinimized()) {
|
||||||
|
basicAuthWindow.restore();
|
||||||
|
}
|
||||||
|
basicAuthWindow.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let allWindows = BrowserWindow.getAllWindows();
|
||||||
|
allWindows = allWindows.find((window) => { return window.winName === windowName });
|
||||||
|
|
||||||
|
// if we couldn't find any window matching the window name
|
||||||
|
// it will render as a new window
|
||||||
|
if (allWindows) {
|
||||||
|
windowConfig.parent = allWindows;
|
||||||
|
}
|
||||||
|
|
||||||
|
basicAuthWindow = new BrowserWindow(windowConfig);
|
||||||
|
basicAuthWindow.setVisibleOnAllWorkspaces(true);
|
||||||
|
basicAuthWindow.loadURL(getTemplatePath());
|
||||||
|
|
||||||
|
// sets the AlwaysOnTop property for the basic auth window
|
||||||
|
// if the main window's AlwaysOnTop is true
|
||||||
|
let focusedWindow = BrowserWindow.getFocusedWindow();
|
||||||
|
if (focusedWindow && focusedWindow.isAlwaysOnTop()) {
|
||||||
|
basicAuthWindow.setAlwaysOnTop(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
basicAuthWindow.once('ready-to-show', () => {
|
||||||
|
basicAuthWindow.show();
|
||||||
|
});
|
||||||
|
|
||||||
|
basicAuthWindow.webContents.on('did-finish-load', () => {
|
||||||
|
basicAuthWindow.webContents.send('hostname', hostname);
|
||||||
|
});
|
||||||
|
|
||||||
|
basicAuthWindow.on('close', () => {
|
||||||
|
destroyWindow();
|
||||||
|
});
|
||||||
|
|
||||||
|
basicAuthWindow.on('closed', () => {
|
||||||
|
destroyWindow();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ipc.on('login', (event, args) => {
|
||||||
|
if (typeof args === 'object' && typeof local.authCallback === 'function') {
|
||||||
|
local.authCallback(args.username, args.password);
|
||||||
|
basicAuthWindow.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ipc.on('close-basic-auth', () => {
|
||||||
|
if (basicAuthWindow) {
|
||||||
|
basicAuthWindow.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys a window
|
||||||
|
*/
|
||||||
|
function destroyWindow() {
|
||||||
|
basicAuthWindow = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
openBasicAuthWindow: openBasicAuthWindow
|
||||||
|
};
|
55
js/basicAuth/renderer.js
Normal file
55
js/basicAuth/renderer.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
'use strict';
|
||||||
|
const electron = require('electron');
|
||||||
|
const ipc = electron.ipcRenderer;
|
||||||
|
|
||||||
|
renderDom();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that renders application data
|
||||||
|
*/
|
||||||
|
function renderDom() {
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
loadContent();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadContent() {
|
||||||
|
let basicAuth = document.getElementById('basicAuth');
|
||||||
|
let cancel = document.getElementById('cancel');
|
||||||
|
|
||||||
|
if (basicAuth) {
|
||||||
|
basicAuth.onsubmit = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
submitForm();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cancel) {
|
||||||
|
cancel.addEventListener('click', () => {
|
||||||
|
ipc.send('close-basic-auth');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that gets invoked on submitting the form
|
||||||
|
*/
|
||||||
|
function submitForm() {
|
||||||
|
let username = document.getElementById('username').value;
|
||||||
|
let password = document.getElementById('password').value;
|
||||||
|
|
||||||
|
if (username && password) {
|
||||||
|
ipc.send('login', { username, password });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the hosts name
|
||||||
|
*/
|
||||||
|
ipc.on('hostname', (event, host) => {
|
||||||
|
let hostname = document.getElementById('hostname');
|
||||||
|
|
||||||
|
if (hostname){
|
||||||
|
hostname.innerHTML = host || 'unknown';
|
||||||
|
}
|
||||||
|
});
|
270
js/config.js
270
js/config.js
@ -4,16 +4,27 @@ const electron = require('electron');
|
|||||||
const app = electron.app;
|
const app = electron.app;
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
const AppDirectory = require('appdirectory');
|
||||||
|
const omit = require('lodash.omit');
|
||||||
|
const pick = require('lodash.pick');
|
||||||
|
const difference = require('lodash.difference');
|
||||||
|
|
||||||
const isDevEnv = require('./utils/misc.js').isDevEnv;
|
const isDevEnv = require('./utils/misc.js').isDevEnv;
|
||||||
const isMac = require('./utils/misc.js').isMac;
|
const isMac = require('./utils/misc.js').isMac;
|
||||||
const getRegistry = require('./utils/getRegistry.js');
|
const getRegistry = require('./utils/getRegistry.js');
|
||||||
|
const log = require('./log.js');
|
||||||
|
const logLevels = require('./enums/logLevels.js');
|
||||||
|
|
||||||
const configFileName = 'Symphony.config';
|
const configFileName = 'Symphony.config';
|
||||||
|
const dirs = new AppDirectory('Symphony');
|
||||||
|
|
||||||
// cached config when first reading files. initially undefined and will be
|
// cached config when first reading files. initially undefined and will be
|
||||||
// updated when read from disk.
|
// updated when read from disk.
|
||||||
let userConfig;
|
let userConfig;
|
||||||
let globalConfig;
|
let globalConfig;
|
||||||
|
|
||||||
|
let ignoreSettings = ['minimizeOnClose', 'launchOnStartup', 'alwaysOnTop', 'url'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to read given field from user config file, if field doesn't exist
|
* Tries to read given field from user config file, if field doesn't exist
|
||||||
* then tries reading from global config. User config is stord in directory:
|
* then tries reading from global config. User config is stord in directory:
|
||||||
@ -29,17 +40,22 @@ let globalConfig;
|
|||||||
*/
|
*/
|
||||||
function getConfigField(fieldName) {
|
function getConfigField(fieldName) {
|
||||||
return getUserConfigField(fieldName)
|
return getUserConfigField(fieldName)
|
||||||
.then(function(value) {
|
.then((value) => {
|
||||||
// got value from user config
|
// got value from user config
|
||||||
return value;
|
return value;
|
||||||
}, function () {
|
}, () => {
|
||||||
// failed to get value from user config, so try global config
|
// failed to get value from user config, so try global config
|
||||||
return getGlobalConfigField(fieldName);
|
return getGlobalConfigField(fieldName);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a specific user config value for a field
|
||||||
|
* @param fieldName
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
function getUserConfigField(fieldName) {
|
function getUserConfigField(fieldName) {
|
||||||
return readUserConfig().then(function(config) {
|
return readUserConfig().then((config) => {
|
||||||
if (typeof fieldName === 'string' && fieldName in config) {
|
if (typeof fieldName === 'string' && fieldName in config) {
|
||||||
return config[fieldName];
|
return config[fieldName];
|
||||||
}
|
}
|
||||||
@ -48,16 +64,25 @@ function getUserConfigField(fieldName) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function readUserConfig() {
|
/**
|
||||||
return new Promise(function(resolve, reject) {
|
* Reads the user config file and returns all the attributes
|
||||||
|
* @param customConfigPath
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
function readUserConfig(customConfigPath) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
if (userConfig) {
|
if (userConfig) {
|
||||||
resolve(userConfig);
|
resolve(userConfig);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let configPath = path.join(app.getPath('userData'), configFileName);
|
let configPath = customConfigPath;
|
||||||
|
|
||||||
fs.readFile(configPath, 'utf8', function(err, data) {
|
if (!configPath) {
|
||||||
|
configPath = path.join(app.getPath('userData'), configFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.readFile(configPath, 'utf8', (err, data) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject('cannot open user config file: ' + configPath + ', error: ' + err);
|
reject('cannot open user config file: ' + configPath + ', error: ' + err);
|
||||||
} else {
|
} else {
|
||||||
@ -74,8 +99,13 @@ function readUserConfig() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a specific user config value for a field
|
||||||
|
* @param fieldName
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
function getGlobalConfigField(fieldName) {
|
function getGlobalConfigField(fieldName) {
|
||||||
return readGlobalConfig().then(function(config) {
|
return readGlobalConfig().then((config) => {
|
||||||
if (typeof fieldName === 'string' && fieldName in config) {
|
if (typeof fieldName === 'string' && fieldName in config) {
|
||||||
return config[fieldName];
|
return config[fieldName];
|
||||||
}
|
}
|
||||||
@ -93,7 +123,7 @@ function getGlobalConfigField(fieldName) {
|
|||||||
* installed app). for dev env, the file is read directly from packed asar file.
|
* installed app). for dev env, the file is read directly from packed asar file.
|
||||||
*/
|
*/
|
||||||
function readGlobalConfig() {
|
function readGlobalConfig() {
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise((resolve, reject) => {
|
||||||
if (globalConfig) {
|
if (globalConfig) {
|
||||||
resolve(globalConfig);
|
resolve(globalConfig);
|
||||||
return;
|
return;
|
||||||
@ -113,7 +143,7 @@ function readGlobalConfig() {
|
|||||||
configPath = path.join(execPath, isMac ? '..' : '', globalConfigFileName);
|
configPath = path.join(execPath, isMac ? '..' : '', globalConfigFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.readFile(configPath, 'utf8', function(err, data) {
|
fs.readFile(configPath, 'utf8', (err, data) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject('cannot open global config file: ' + configPath + ', error: ' + err);
|
reject('cannot open global config file: ' + configPath + ', error: ' + err);
|
||||||
} else {
|
} else {
|
||||||
@ -124,12 +154,12 @@ function readGlobalConfig() {
|
|||||||
reject('can not parse config file data: ' + data + ', error: ' + err);
|
reject('can not parse config file data: ' + data + ', error: ' + err);
|
||||||
}
|
}
|
||||||
getRegistry('PodUrl')
|
getRegistry('PodUrl')
|
||||||
.then(function(url) {
|
.then((url) => {
|
||||||
globalConfig.url = url;
|
globalConfig.url = url;
|
||||||
resolve(globalConfig);
|
resolve(globalConfig);
|
||||||
}).catch(function () {
|
}).catch(() => {
|
||||||
resolve(globalConfig);
|
resolve(globalConfig);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -143,21 +173,27 @@ function readGlobalConfig() {
|
|||||||
*/
|
*/
|
||||||
function updateConfigField(fieldName, newValue) {
|
function updateConfigField(fieldName, newValue) {
|
||||||
return readUserConfig()
|
return readUserConfig()
|
||||||
.then(function(config) {
|
.then((config) => {
|
||||||
return saveUserConfig(fieldName, newValue, config);
|
return saveUserConfig(fieldName, newValue, config);
|
||||||
},
|
}, () => {
|
||||||
function() {
|
// in case config doesn't exist, can't read or is corrupted.
|
||||||
// in case config doesn't exist, can't read or is corrupted.
|
// add configVersion - just in case in future we need to provide
|
||||||
// add configVersion - just in case in future we need to provide
|
// upgrade capabilities.
|
||||||
// upgrade capabilities.
|
return saveUserConfig(fieldName, newValue, {
|
||||||
return saveUserConfig(fieldName, newValue, {
|
configVersion: '1.0.0'
|
||||||
configVersion: '1.0.0'
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves an updated value to the user config
|
||||||
|
* @param fieldName
|
||||||
|
* @param newValue
|
||||||
|
* @param oldConfig
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
function saveUserConfig(fieldName, newValue, oldConfig) {
|
function saveUserConfig(fieldName, newValue, oldConfig) {
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise((resolve, reject) => {
|
||||||
let configPath = path.join(app.getPath('userData'), configFileName);
|
let configPath = path.join(app.getPath('userData'), configFileName);
|
||||||
|
|
||||||
if (!oldConfig || !fieldName) {
|
if (!oldConfig || !fieldName) {
|
||||||
@ -182,17 +218,183 @@ function saveUserConfig(fieldName, newValue, oldConfig) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the existing user config settings by removing
|
||||||
|
* 'minimizeOnClose', 'launchOnStartup', 'url' and 'alwaysOnTop'
|
||||||
|
* @param {Object} oldUserConfig the old user config object
|
||||||
|
*/
|
||||||
|
function updateUserConfig(oldUserConfig) {
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
|
// create a new object from the old user config
|
||||||
|
// by ommitting the user related settings from
|
||||||
|
// the old user config
|
||||||
|
let newUserConfig = omit(oldUserConfig, ignoreSettings);
|
||||||
|
let newUserConfigString = JSON.stringify(newUserConfig, null, 2);
|
||||||
|
|
||||||
|
// get the user config path
|
||||||
|
let userConfigFile;
|
||||||
|
if (isMac) {
|
||||||
|
userConfigFile = path.join(dirs.userConfig(), configFileName);
|
||||||
|
} else {
|
||||||
|
userConfigFile = path.join(app.getPath('userData'), configFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!userConfigFile) {
|
||||||
|
return reject('user config file doesn\'t exist');
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the new user config changes to the user config file
|
||||||
|
fs.writeFileSync(userConfigFile, newUserConfigString, 'utf-8');
|
||||||
|
|
||||||
|
return resolve();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manipulates user config on windows
|
||||||
|
* @param {String} perUserInstall - Is a flag to determine if we are installing for an individual user
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
function updateUserConfigWin(perUserInstall) {
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
|
// we get the user config path using electron
|
||||||
|
const userConfigFile = path.join(app.getPath('userData'), configFileName);
|
||||||
|
|
||||||
|
// if it's not a per user installation or if the
|
||||||
|
// user config file doesn't exist, we simple move on
|
||||||
|
if (!perUserInstall || !fs.existsSync(userConfigFile)) {
|
||||||
|
log.send(logLevels.WARN, 'config: Could not find the user config file!');
|
||||||
|
reject();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In case the file exists, we remove it so that all the
|
||||||
|
// values are fetched from the global config
|
||||||
|
// https://perzoinc.atlassian.net/browse/ELECTRON-126
|
||||||
|
readUserConfig(userConfigFile).then((data) => {
|
||||||
|
resolve(updateUserConfig(data));
|
||||||
|
}).catch((err) => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manipulates user config on macOS
|
||||||
|
* @param {String} globalConfigPath - The global config path from installer
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
function updateUserConfigMac() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const userConfigFile = path.join(dirs.userConfig(), configFileName);
|
||||||
|
|
||||||
|
// if user config file does't exist, just use the global config settings
|
||||||
|
// i.e. until an user makes changes manually using the menu items
|
||||||
|
if (!fs.existsSync(userConfigFile)) {
|
||||||
|
log.send(logLevels.WARN, 'config: Could not find the user config file!');
|
||||||
|
reject();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In case the file exists, we remove it so that all the
|
||||||
|
// values are fetched from the global config
|
||||||
|
// https://perzoinc.atlassian.net/browse/ELECTRON-126
|
||||||
|
readUserConfig(userConfigFile).then((data) => {
|
||||||
|
resolve(updateUserConfig(data));
|
||||||
|
}).catch((err) => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that tries to grab multiple config field from user config
|
||||||
|
* if field doesn't exist tries reading from global config
|
||||||
|
*
|
||||||
|
* @param {Array} fieldNames - array of config filed names
|
||||||
|
* @returns {Promise} - object all the config data from user and global config
|
||||||
|
*/
|
||||||
|
function getMultipleConfigField(fieldNames) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let userConfigData;
|
||||||
|
|
||||||
|
if (!fieldNames && fieldNames.length < 0) {
|
||||||
|
reject('cannot read config file, invalid fields');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reads user config data
|
||||||
|
readUserConfig().then((config) => {
|
||||||
|
userConfigData = pick(config, fieldNames);
|
||||||
|
let userConfigKeys = userConfigData ? Object.keys(userConfigData) : undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Condition to validate data from user config,
|
||||||
|
* if all the required fields are not present
|
||||||
|
* this tries to fetch the remaining fields from global config
|
||||||
|
*/
|
||||||
|
if (!userConfigKeys || userConfigKeys.length < fieldNames.length) {
|
||||||
|
|
||||||
|
// remainingConfig - config field that are not present in the user config
|
||||||
|
let remainingConfig = difference(fieldNames, userConfigKeys);
|
||||||
|
|
||||||
|
if (remainingConfig && Object.keys(remainingConfig).length > 0) {
|
||||||
|
readGlobalConfig().then((globalConfigData) => {
|
||||||
|
// assigns the remaining fields from global config to the user config
|
||||||
|
userConfigData = Object.assign(userConfigData, pick(globalConfigData, remainingConfig));
|
||||||
|
resolve(userConfigData);
|
||||||
|
}).catch((err) => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
resolve(userConfigData);
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
// This reads global config if there was any
|
||||||
|
// error while reading user config
|
||||||
|
readGlobalConfig().then((config) => {
|
||||||
|
userConfigData = pick(config, fieldNames);
|
||||||
|
resolve(userConfigData);
|
||||||
|
}).catch((err) => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the cached config
|
||||||
|
*/
|
||||||
function clearCachedConfigs() {
|
function clearCachedConfigs() {
|
||||||
userConfig = null;
|
userConfig = null;
|
||||||
globalConfig = null;
|
globalConfig = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getConfigField,
|
|
||||||
updateConfigField,
|
|
||||||
configFileName,
|
configFileName,
|
||||||
|
|
||||||
|
getConfigField,
|
||||||
|
|
||||||
|
updateConfigField,
|
||||||
|
updateUserConfigWin,
|
||||||
|
updateUserConfigMac,
|
||||||
|
getMultipleConfigField,
|
||||||
|
|
||||||
// items below here are only exported for testing, do NOT use!
|
// items below here are only exported for testing, do NOT use!
|
||||||
saveUserConfig,
|
saveUserConfig,
|
||||||
clearCachedConfigs
|
clearCachedConfigs
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -12,23 +12,32 @@
|
|||||||
// renderer process, this will have to do. See github issue posted here to
|
// renderer process, this will have to do. See github issue posted here to
|
||||||
// electron: https://github.com/electron/electron/issues/9312
|
// electron: https://github.com/electron/electron/issues/9312
|
||||||
|
|
||||||
var { ipcRenderer } = require('electron');
|
const { ipcRenderer } = require('electron');
|
||||||
|
|
||||||
|
let nextId = 0;
|
||||||
var nextId = 0;
|
let includes = [].includes;
|
||||||
var includes = [].includes;
|
|
||||||
|
|
||||||
function getNextId() {
|
function getNextId() {
|
||||||
return ++nextId;
|
return ++nextId;
|
||||||
}
|
}
|
||||||
|
|
||||||
// |options.type| can not be empty and has to include 'window' or 'screen'.
|
/**
|
||||||
|
* Checks if the options and their types are valid
|
||||||
|
* @param options |options.type| can not be empty and has to include 'window' or 'screen'.
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
function isValid(options) {
|
function isValid(options) {
|
||||||
return ((options != null ? options.types : undefined) != null) && Array.isArray(options.types);
|
return ((options !== null ? options.types : undefined) !== null) && Array.isArray(options.types);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the sources for capturing screens / windows
|
||||||
|
* @param options
|
||||||
|
* @param callback
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
function getSources(options, callback) {
|
function getSources(options, callback) {
|
||||||
var captureScreen, captureWindow, id;
|
let captureScreen, captureWindow, id;
|
||||||
if (!isValid(options)) {
|
if (!isValid(options)) {
|
||||||
return callback(new Error('Invalid options'));
|
return callback(new Error('Invalid options'));
|
||||||
}
|
}
|
||||||
@ -36,33 +45,34 @@ function getSources(options, callback) {
|
|||||||
captureScreen = includes.call(options.types, 'screen');
|
captureScreen = includes.call(options.types, 'screen');
|
||||||
|
|
||||||
let updatedOptions = options;
|
let updatedOptions = options;
|
||||||
if (updatedOptions.thumbnailSize == null) {
|
if (!updatedOptions.thumbnailSize) {
|
||||||
updatedOptions.thumbnailSize = {
|
updatedOptions.thumbnailSize = {
|
||||||
width: 150,
|
width: 150,
|
||||||
height: 150
|
height: 150
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
id = getNextId();
|
id = getNextId();
|
||||||
ipcRenderer.send('ELECTRON_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', captureWindow, captureScreen, updatedOptions.thumbnailSize, id);
|
ipcRenderer.send('ELECTRON_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', captureWindow, captureScreen, updatedOptions.thumbnailSize, id);
|
||||||
|
|
||||||
return ipcRenderer.once('ELECTRON_RENDERER_DESKTOP_CAPTURER_RESULT_' + id, function (event, sources) {
|
return ipcRenderer.once('ELECTRON_RENDERER_DESKTOP_CAPTURER_RESULT_' + id, function(event, sources) {
|
||||||
var source;
|
let source;
|
||||||
callback(null, (function () {
|
callback(null, (function() {
|
||||||
var i, len, results
|
let i, len, results;
|
||||||
results = [];
|
results = [];
|
||||||
for (i = 0, len = sources.length; i < len; i++) {
|
for (i = 0, len = sources.length; i < len; i++) {
|
||||||
source = sources[i]
|
source = sources[i];
|
||||||
results.push({
|
results.push({
|
||||||
id: source.id,
|
id: source.id,
|
||||||
name: source.name,
|
name: source.name,
|
||||||
thumbnail: source.thumbnail
|
thumbnail: source.thumbnail
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return results
|
return results;
|
||||||
|
|
||||||
}()));
|
}()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = getSources;
|
module.exports = getSources;
|
25
js/dialogs/showBasicAuth.js
Normal file
25
js/dialogs/showBasicAuth.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const electron = require('electron');
|
||||||
|
|
||||||
|
const basicAuth = require('../basicAuth');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Having a proxy or hosts that requires authentication will allow user to
|
||||||
|
* enter their credentials 'username' & 'password'
|
||||||
|
*/
|
||||||
|
electron.app.on('login', (event, webContents, request, authInfo, callback) => {
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
// name of the host to display
|
||||||
|
let hostname = authInfo.host || authInfo.realm;
|
||||||
|
let browserWin = electron.BrowserWindow.fromWebContents(webContents);
|
||||||
|
let windowName = browserWin.winName || '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens an electron modal window in which
|
||||||
|
* user can enter credentials fot the host
|
||||||
|
*/
|
||||||
|
basicAuth.openBasicAuthWindow(windowName, hostname, callback);
|
||||||
|
});
|
@ -11,14 +11,15 @@ const logLevels = require('../enums/logLevels.js');
|
|||||||
* @param {String} url Url that failed
|
* @param {String} url Url that failed
|
||||||
* @param {String} errorDesc Description of error
|
* @param {String} errorDesc Description of error
|
||||||
* @param {Number} errorCode Error code
|
* @param {Number} errorCode Error code
|
||||||
* @param {callback} retryCallback Callback when user clicks reload
|
* @param {function} retryCallback Callback when user clicks reload
|
||||||
|
* @param {Boolean} showDialog Indicates if a dialog need to be show to a user
|
||||||
*/
|
*/
|
||||||
function showLoadFailure(win, url, errorDesc, errorCode, retryCallback) {
|
function showLoadFailure(win, url, errorDesc, errorCode, retryCallback, showDialog) {
|
||||||
let msg;
|
let msg;
|
||||||
if (url) {
|
if (url) {
|
||||||
msg = 'Error loading URL:\n' + url;
|
msg = 'Error loading URL:\n' + url;
|
||||||
} else {
|
} else {
|
||||||
msg = 'Error loading window'
|
msg = 'Error loading window';
|
||||||
}
|
}
|
||||||
if (errorDesc) {
|
if (errorDesc) {
|
||||||
msg += '\n\n' + errorDesc;
|
msg += '\n\n' + errorDesc;
|
||||||
@ -27,18 +28,20 @@ function showLoadFailure(win, url, errorDesc, errorCode, retryCallback) {
|
|||||||
msg += '\n\nError Code: ' + errorCode;
|
msg += '\n\nError Code: ' + errorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
electron.dialog.showMessageBox(win, {
|
if (showDialog) {
|
||||||
type: 'error',
|
electron.dialog.showMessageBox(win, {
|
||||||
buttons: [ 'Reload', 'Ignore' ],
|
type: 'error',
|
||||||
defaultId: 0,
|
buttons: ['Reload', 'Ignore'],
|
||||||
cancelId: 1,
|
defaultId: 0,
|
||||||
noLink: true,
|
cancelId: 1,
|
||||||
title: 'Loading Error',
|
noLink: true,
|
||||||
message: msg
|
title: 'Loading Error',
|
||||||
}, response);
|
message: msg
|
||||||
|
}, response);
|
||||||
|
}
|
||||||
|
|
||||||
log.send(logLevels.WARNING, 'Load failure msg: ' + errorDesc +
|
log.send(logLevels.WARNING, 'Load failure msg: ' + errorDesc +
|
||||||
' errorCode: ' + errorCode + ' for url:' + url);
|
' errorCode: ' + errorCode + ' for url:' + url);
|
||||||
|
|
||||||
// async handle of user input
|
// async handle of user input
|
||||||
function response(buttonId) {
|
function response(buttonId) {
|
||||||
@ -53,11 +56,11 @@ function showLoadFailure(win, url, errorDesc, errorCode, retryCallback) {
|
|||||||
* Show message indicating network connectivity has been lost.
|
* Show message indicating network connectivity has been lost.
|
||||||
* @param {BrowserWindow} win Window to host dialog
|
* @param {BrowserWindow} win Window to host dialog
|
||||||
* @param {String} url Url that failed
|
* @param {String} url Url that failed
|
||||||
* @param {callback} retryCallback Callback when user clicks reload
|
* @param {function} retryCallback Callback when user clicks reload
|
||||||
*/
|
*/
|
||||||
function showNetworkConnectivityError(win, url, retryCallback) {
|
function showNetworkConnectivityError(win, url, retryCallback) {
|
||||||
var errorDesc = 'Network connectivity has been lost, check your internet connection.';
|
let errorDesc = 'Network connectivity has been lost, check your internet connection.';
|
||||||
showLoadFailure(win, url, errorDesc, 0, retryCallback);
|
showLoadFailure(win, url, errorDesc, 0, retryCallback, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { showLoadFailure, showNetworkConnectivityError };
|
module.exports = { showLoadFailure, showNetworkConnectivityError };
|
@ -19,12 +19,13 @@ local.ipcRenderer.on('downloadProgress', () => {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Open file in default app.
|
* Open file in default app.
|
||||||
|
* @param id
|
||||||
*/
|
*/
|
||||||
function openFile(id) {
|
function openFile(id) {
|
||||||
let fileIndex = local.downloadItems.findIndex((item) => {
|
let fileIndex = local.downloadItems.findIndex((item) => {
|
||||||
return item._id === id
|
return item._id === id;
|
||||||
});
|
});
|
||||||
if (fileIndex !== -1){
|
if (fileIndex !== -1) {
|
||||||
let openResponse = remote.shell.openExternal(`file:///${local.downloadItems[fileIndex].savedPath}`);
|
let openResponse = remote.shell.openExternal(`file:///${local.downloadItems[fileIndex].savedPath}`);
|
||||||
if (!openResponse) {
|
if (!openResponse) {
|
||||||
remote.dialog.showErrorBox("File not found", 'The file you are trying to open cannot be found in the specified path.');
|
remote.dialog.showErrorBox("File not found", 'The file you are trying to open cannot be found in the specified path.');
|
||||||
@ -34,10 +35,11 @@ function openFile(id) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Show downloaded file in explorer or finder.
|
* Show downloaded file in explorer or finder.
|
||||||
|
* @param id
|
||||||
*/
|
*/
|
||||||
function showInFinder(id) {
|
function showInFinder(id) {
|
||||||
let showFileIndex = local.downloadItems.findIndex((item) => {
|
let showFileIndex = local.downloadItems.findIndex((item) => {
|
||||||
return item._id === id
|
return item._id === id;
|
||||||
});
|
});
|
||||||
if (showFileIndex !== -1) {
|
if (showFileIndex !== -1) {
|
||||||
let showResponse = remote.shell.showItemInFolder(local.downloadItems[showFileIndex].savedPath);
|
let showResponse = remote.shell.showItemInFolder(local.downloadItems[showFileIndex].savedPath);
|
||||||
@ -47,12 +49,17 @@ function showInFinder(id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the document object model
|
||||||
|
* @param arg
|
||||||
|
*/
|
||||||
function createDOM(arg) {
|
function createDOM(arg) {
|
||||||
|
|
||||||
if (arg && arg._id) {
|
if (arg && arg._id) {
|
||||||
|
let fileDisplayName = getFileDisplayName(arg.fileName);
|
||||||
|
let downloadItemKey = arg._id;
|
||||||
|
|
||||||
local.downloadItems.push(arg);
|
local.downloadItems.push(arg);
|
||||||
let downloadItemKey = arg._id;
|
|
||||||
|
|
||||||
let ul = document.getElementById('download-main');
|
let ul = document.getElementById('download-main');
|
||||||
if (ul) {
|
if (ul) {
|
||||||
@ -102,7 +109,8 @@ function createDOM(arg) {
|
|||||||
|
|
||||||
let h2FileName = document.createElement('h2');
|
let h2FileName = document.createElement('h2');
|
||||||
h2FileName.classList.add('text-cutoff');
|
h2FileName.classList.add('text-cutoff');
|
||||||
h2FileName.innerHTML = arg.fileName;
|
h2FileName.innerHTML = fileDisplayName;
|
||||||
|
h2FileName.title = fileDisplayName;
|
||||||
fileNameDiv.appendChild(h2FileName);
|
fileNameDiv.appendChild(h2FileName);
|
||||||
|
|
||||||
let fileProgressTitle = document.createElement('span');
|
let fileProgressTitle = document.createElement('span');
|
||||||
@ -149,6 +157,9 @@ function createDOM(arg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initiate the download manager
|
||||||
|
*/
|
||||||
function initiate() {
|
function initiate() {
|
||||||
let mainFooter = document.getElementById('footer');
|
let mainFooter = document.getElementById('footer');
|
||||||
let mainDownloadDiv = document.getElementById('download-manager-footer');
|
let mainDownloadDiv = document.getElementById('download-manager-footer');
|
||||||
@ -159,7 +170,7 @@ function initiate() {
|
|||||||
|
|
||||||
let ulFind = document.getElementById('download-main');
|
let ulFind = document.getElementById('download-main');
|
||||||
|
|
||||||
if (!ulFind){
|
if (!ulFind) {
|
||||||
let uList = document.createElement('ul');
|
let uList = document.createElement('ul');
|
||||||
uList.id = 'download-main';
|
uList.id = 'download-main';
|
||||||
mainDownloadDiv.appendChild(uList);
|
mainDownloadDiv.appendChild(uList);
|
||||||
@ -167,7 +178,7 @@ function initiate() {
|
|||||||
|
|
||||||
let closeSpanFind = document.getElementById('close-download-bar');
|
let closeSpanFind = document.getElementById('close-download-bar');
|
||||||
|
|
||||||
if (!closeSpanFind){
|
if (!closeSpanFind) {
|
||||||
let closeSpan = document.createElement('span');
|
let closeSpan = document.createElement('span');
|
||||||
closeSpan.id = 'close-download-bar';
|
closeSpan.id = 'close-download-bar';
|
||||||
closeSpan.classList.add('close-download-bar');
|
closeSpan.classList.add('close-download-bar');
|
||||||
@ -185,4 +196,33 @@ function initiate() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a file display name for the download item
|
||||||
|
*/
|
||||||
|
function getFileDisplayName(fileName) {
|
||||||
|
let fileList = local.downloadItems;
|
||||||
|
let fileNameCount = 0;
|
||||||
|
let fileDisplayName = fileName;
|
||||||
|
|
||||||
|
/* Check if a file with the same name exists
|
||||||
|
* (akin to the user downloading a file with the same name again)
|
||||||
|
* in the download bar
|
||||||
|
*/
|
||||||
|
for (let i = 0; i < fileList.length; i++) {
|
||||||
|
if (fileName === fileList[i].fileName) {
|
||||||
|
fileNameCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If it exists, add a count to the name like how Chrome does */
|
||||||
|
if (fileNameCount) {
|
||||||
|
let extLastIndex = fileDisplayName.lastIndexOf('.');
|
||||||
|
let fileCount = ' (' + fileNameCount + ')';
|
||||||
|
|
||||||
|
fileDisplayName = fileDisplayName.slice(0, extLastIndex) + fileCount + fileDisplayName.slice(extLastIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileDisplayName;
|
||||||
}
|
}
|
@ -1,7 +1,11 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var keyMirror = require('keymirror');
|
let keyMirror = require('keymirror');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set of APIs exposed to the remote object
|
||||||
|
* @type {Object}
|
||||||
|
*/
|
||||||
const cmds = keyMirror({
|
const cmds = keyMirror({
|
||||||
isOnline: null,
|
isOnline: null,
|
||||||
registerLogger: null,
|
registerLogger: null,
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var keyMirror = require('keymirror');
|
let keyMirror = require('keymirror');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The different log levels
|
||||||
|
* @type {Object}
|
||||||
|
*/
|
||||||
module.exports = keyMirror({
|
module.exports = keyMirror({
|
||||||
ERROR: null,
|
ERROR: null,
|
||||||
CONFLICT: null,
|
CONFLICT: null,
|
||||||
|
59
js/log.js
59
js/log.js
@ -1,16 +1,26 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const getCmdLineArg = require('./utils/getCmdLineArg.js')
|
const getCmdLineArg = require('./utils/getCmdLineArg.js');
|
||||||
|
const { isDevEnv } = require('./utils/misc');
|
||||||
|
const logLevels = require('./enums/logLevels.js');
|
||||||
|
|
||||||
const MAX_LOG_QUEUE_LENGTH = 100;
|
const MAX_LOG_QUEUE_LENGTH = 100;
|
||||||
|
|
||||||
|
let electronLog;
|
||||||
|
|
||||||
class Logger {
|
class Logger {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
// browser window that has registered a logger
|
// browser window that has registered a logger
|
||||||
this.logWindow = null;
|
this.logWindow = null;
|
||||||
|
|
||||||
// holds log messages received before logger has been registered.
|
// holds log messages received before logger has been registered.
|
||||||
this.logQueue = [];
|
this.logQueue = [];
|
||||||
|
|
||||||
|
// Initializes the local logger
|
||||||
|
if (isDevEnv) {
|
||||||
|
initializeLocalLogger();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,6 +35,10 @@ class Logger {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isDevEnv) {
|
||||||
|
logLocally(level, details);
|
||||||
|
}
|
||||||
|
|
||||||
let logMsg = {
|
let logMsg = {
|
||||||
level: level,
|
level: level,
|
||||||
details: details,
|
details: details,
|
||||||
@ -45,18 +59,22 @@ class Logger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a window instance for the remote object
|
||||||
|
* @param win
|
||||||
|
*/
|
||||||
setLogWindow(win) {
|
setLogWindow(win) {
|
||||||
this.logWindow = win;
|
this.logWindow = win;
|
||||||
|
|
||||||
if (this.logWindow) {
|
if (this.logWindow) {
|
||||||
var logMsg = {};
|
let logMsg = {};
|
||||||
|
|
||||||
if (Array.isArray(this.logQueue)) {
|
if (Array.isArray(this.logQueue)) {
|
||||||
logMsg.msgs = this.logQueue;
|
logMsg.msgs = this.logQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// configure desired log level and send pending log msgs
|
// configure desired log level and send pending log msgs
|
||||||
let logLevel = getCmdLineArg(process.argv, '--logLevel=');
|
let logLevel = getCmdLineArg(process.argv, '--logLevel=', false);
|
||||||
if (logLevel) {
|
if (logLevel) {
|
||||||
let level = logLevel.split('=')[1];
|
let level = logLevel.split('=')[1];
|
||||||
if (level) {
|
if (level) {
|
||||||
@ -64,7 +82,7 @@ class Logger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getCmdLineArg(process.argv, '--enableConsoleLogging')) {
|
if (getCmdLineArg(process.argv, '--enableConsoleLogging', false)) {
|
||||||
logMsg.showInConsole = true;
|
logMsg.showInConsole = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,11 +95,40 @@ class Logger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var loggerInstance = new Logger();
|
let loggerInstance = new Logger();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the electron logger for local logging
|
||||||
|
*/
|
||||||
|
function initializeLocalLogger() {
|
||||||
|
// eslint-disable-next-line global-require
|
||||||
|
electronLog = require('electron-log');
|
||||||
|
electronLog.transports.file.level = 'debug';
|
||||||
|
electronLog.transports.file.format = '{h}:{i}:{s}:{ms} {text}';
|
||||||
|
electronLog.transports.file.maxSize = 10 * 1024 * 1024;
|
||||||
|
electronLog.transports.file.appName = 'Symphony';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs locally using the electron-logger
|
||||||
|
* @param level
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
function logLocally(level, message) {
|
||||||
|
switch (level) {
|
||||||
|
case logLevels.ERROR: electronLog.error(message); break;
|
||||||
|
case logLevels.CONFLICT: electronLog.error(message); break;
|
||||||
|
case logLevels.WARN: electronLog.warn(message); break;
|
||||||
|
case logLevels.ACTION: electronLog.warn(message); break;
|
||||||
|
case logLevels.INFO: electronLog.info(message); break;
|
||||||
|
case logLevels.DEBUG: electronLog.debug(message); break;
|
||||||
|
default: electronLog.debug(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Logger class is only exposed for testing purposes.
|
// Logger class is only exposed for testing purposes.
|
||||||
module.exports = {
|
module.exports = {
|
||||||
Logger: Logger,
|
Logger: Logger,
|
||||||
send: loggerInstance.send.bind(loggerInstance),
|
send: loggerInstance.send.bind(loggerInstance),
|
||||||
setLogWindow: loggerInstance.setLogWindow.bind(loggerInstance)
|
setLogWindow: loggerInstance.setLogWindow.bind(loggerInstance)
|
||||||
}
|
};
|
||||||
|
158
js/main.js
158
js/main.js
@ -1,20 +1,23 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
// Third Party Dependencies
|
||||||
const electron = require('electron');
|
const electron = require('electron');
|
||||||
const app = electron.app;
|
const app = electron.app;
|
||||||
|
const crashReporter = electron.crashReporter;
|
||||||
const nodeURL = require('url');
|
const nodeURL = require('url');
|
||||||
const shellPath = require('shell-path');
|
const shellPath = require('shell-path');
|
||||||
const squirrelStartup = require('electron-squirrel-startup');
|
const squirrelStartup = require('electron-squirrel-startup');
|
||||||
const AutoLaunch = require('auto-launch');
|
const AutoLaunch = require('auto-launch');
|
||||||
const urlParser = require('url');
|
const urlParser = require('url');
|
||||||
const { getConfigField } = require('./config.js');
|
|
||||||
|
// Local Dependencies
|
||||||
|
const {getConfigField, updateUserConfigWin, updateUserConfigMac} = require('./config.js');
|
||||||
|
const {setCheckboxValues} = require('./menus/menuTemplate.js');
|
||||||
const { isMac, isDevEnv } = require('./utils/misc.js');
|
const { isMac, isDevEnv } = require('./utils/misc.js');
|
||||||
const protocolHandler = require('./protocolHandler');
|
const protocolHandler = require('./protocolHandler');
|
||||||
const getCmdLineArg = require('./utils/getCmdLineArg.js');
|
const getCmdLineArg = require('./utils/getCmdLineArg.js');
|
||||||
const childProcess = require('child_process');
|
const log = require('./log.js');
|
||||||
const path = require('path');
|
const logLevels = require('./enums/logLevels.js');
|
||||||
const AppDirectory = require('appdirectory');
|
|
||||||
const dirs = new AppDirectory('Symphony');
|
|
||||||
const Crypto = require('./cryptoLib');
|
const Crypto = require('./cryptoLib');
|
||||||
const crypto = new Crypto();
|
const crypto = new Crypto();
|
||||||
|
|
||||||
@ -43,6 +46,23 @@ require('./memoryMonitor.js');
|
|||||||
|
|
||||||
const windowMgr = require('./windowMgr.js');
|
const windowMgr = require('./windowMgr.js');
|
||||||
|
|
||||||
|
getConfigField('url')
|
||||||
|
.then(initializeCrashReporter)
|
||||||
|
.catch(app.quit);
|
||||||
|
|
||||||
|
function initializeCrashReporter(podUrl) {
|
||||||
|
|
||||||
|
getConfigField('crashReporter')
|
||||||
|
.then((crashReporterConfig) => {
|
||||||
|
crashReporter.start({companyName: crashReporterConfig.companyName, submitURL: crashReporterConfig.submitURL, uploadToServer: crashReporterConfig.uploadToServer, extra: {'process': 'main', podUrl: podUrl}});
|
||||||
|
log.send(logLevels.INFO, 'initialized crash reporter on the main process!');
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
log.send(logLevels.ERROR, 'Unable to initialize crash reporter in the main process. Error is -> ' + err);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// only allow a single instance of app.
|
// only allow a single instance of app.
|
||||||
const shouldQuit = app.makeSingleInstance((argv) => {
|
const shouldQuit = app.makeSingleInstance((argv) => {
|
||||||
// Someone tried to run a second instance, we should focus our window.
|
// Someone tried to run a second instance, we should focus our window.
|
||||||
@ -84,13 +104,20 @@ if (isMac) {
|
|||||||
* initialization and is ready to create browser windows.
|
* initialization and is ready to create browser windows.
|
||||||
* Some APIs can only be used after this event occurs.
|
* Some APIs can only be used after this event occurs.
|
||||||
*/
|
*/
|
||||||
app.on('ready', setupThenOpenMainWindow);
|
app.on('ready', readConfigThenOpenMainWindow);
|
||||||
|
|
||||||
app.on('window-all-closed', function () {
|
/**
|
||||||
|
* Is triggered when all the windows are closed
|
||||||
|
* In which case we quit the app
|
||||||
|
*/
|
||||||
|
app.on('window-all-closed', function() {
|
||||||
app.quit();
|
app.quit();
|
||||||
});
|
});
|
||||||
|
|
||||||
app.on('activate', function () {
|
/**
|
||||||
|
* Is triggered when the app is up & running
|
||||||
|
*/
|
||||||
|
app.on('activate', function() {
|
||||||
if (windowMgr.isMainWindow(null)) {
|
if (windowMgr.isMainWindow(null)) {
|
||||||
setupThenOpenMainWindow();
|
setupThenOpenMainWindow();
|
||||||
} else {
|
} else {
|
||||||
@ -109,26 +136,46 @@ app.on('will-quit', function (e) {
|
|||||||
// and registry keys in windows
|
// and registry keys in windows
|
||||||
app.setAsDefaultProtocolClient('symphony');
|
app.setAsDefaultProtocolClient('symphony');
|
||||||
|
|
||||||
// This event is emitted only on macOS
|
/**
|
||||||
// at this moment, support for windows
|
* This event is emitted only on macOS
|
||||||
// is in pipeline (https://github.com/electron/electron/pull/8052)
|
* at this moment, support for windows
|
||||||
app.on('open-url', function (event, url) {
|
* is in pipeline (https://github.com/electron/electron/pull/8052)
|
||||||
|
*/
|
||||||
|
app.on('open-url', function(event, url) {
|
||||||
handleProtocolAction(url);
|
handleProtocolAction(url);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the config fields that are required for the menu items
|
||||||
|
* then opens the main window
|
||||||
|
*
|
||||||
|
* This is a workaround for the issue where the menu template was returned
|
||||||
|
* even before the config data was populated
|
||||||
|
* https://perzoinc.atlassian.net/browse/ELECTRON-154
|
||||||
|
*/
|
||||||
|
function readConfigThenOpenMainWindow() {
|
||||||
|
setCheckboxValues()
|
||||||
|
.then(setupThenOpenMainWindow)
|
||||||
|
.catch(setupThenOpenMainWindow)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up the app (to handle various things like config changes, protocol handling etc.)
|
||||||
|
* and opens the main window
|
||||||
|
*/
|
||||||
function setupThenOpenMainWindow() {
|
function setupThenOpenMainWindow() {
|
||||||
|
|
||||||
processProtocolAction(process.argv);
|
processProtocolAction(process.argv);
|
||||||
|
|
||||||
isAppAlreadyOpen = true;
|
isAppAlreadyOpen = true;
|
||||||
|
|
||||||
// allows installer to launch app and set auto startup mode then
|
// allows installer to launch app and set appropriate global / user config params.
|
||||||
// immediately quit.
|
|
||||||
let hasInstallFlag = getCmdLineArg(process.argv, '--install', true);
|
let hasInstallFlag = getCmdLineArg(process.argv, '--install', true);
|
||||||
|
let perUserInstall = getCmdLineArg(process.argv, '--peruser', true);
|
||||||
if (!isMac && hasInstallFlag) {
|
if (!isMac && hasInstallFlag) {
|
||||||
getConfigField('launchOnStartup')
|
getConfigField('launchOnStartup')
|
||||||
.then(setStartup)
|
.then(setStartup)
|
||||||
.then(updateUserConfigWin)
|
.then(() => updateUserConfigWin(perUserInstall))
|
||||||
.then(app.quit)
|
.then(app.quit)
|
||||||
.catch(app.quit);
|
.catch(app.quit);
|
||||||
return;
|
return;
|
||||||
@ -140,8 +187,11 @@ function setupThenOpenMainWindow() {
|
|||||||
// as the app is launched as a root user we don't get
|
// as the app is launched as a root user we don't get
|
||||||
// access to the config file
|
// access to the config file
|
||||||
let launchOnStartup = process.argv[3];
|
let launchOnStartup = process.argv[3];
|
||||||
updateUserConfigMac()
|
// We wire this in via the post install script
|
||||||
.then(setStartup(launchOnStartup))
|
// to get the config file path where the app is installed
|
||||||
|
let appGlobalConfigPath = process.argv[2];
|
||||||
|
setStartup(launchOnStartup)
|
||||||
|
.then(() => updateUserConfigMac(appGlobalConfigPath))
|
||||||
.then(app.quit)
|
.then(app.quit)
|
||||||
.catch(app.quit);
|
.catch(app.quit);
|
||||||
return;
|
return;
|
||||||
@ -154,56 +204,34 @@ function setupThenOpenMainWindow() {
|
|||||||
electron.screen.on('display-removed', windowMgr.verifyDisplays);
|
electron.screen.on('display-removed', windowMgr.verifyDisplays);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setStartup(lStartup){
|
/**
|
||||||
|
* Sets Symphony on startup
|
||||||
|
* @param lStartup
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
function setStartup(lStartup) {
|
||||||
return symphonyAutoLauncher.isEnabled()
|
return symphonyAutoLauncher.isEnabled()
|
||||||
.then(function(isEnabled){
|
.then(function(isEnabled) {
|
||||||
if (!isEnabled && lStartup) {
|
if (!isEnabled && lStartup) {
|
||||||
return symphonyAutoLauncher.enable();
|
return symphonyAutoLauncher.enable();
|
||||||
}
|
|
||||||
|
|
||||||
if (isEnabled && !lStartup) {
|
|
||||||
return symphonyAutoLauncher.disable();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to overwrite user config on mac installer
|
|
||||||
function updateUserConfigMac() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let userConfigPath = dirs.userConfig() + '/';
|
|
||||||
let globalConfigPath = process.argv[2];
|
|
||||||
let userName = process.env.USER;
|
|
||||||
|
|
||||||
childProcess.exec(`rsync -r "${globalConfigPath}" "${userConfigPath}" && chown -R "${userName}" "${userConfigPath}"`, {timeout: 60000}, (err) => {
|
|
||||||
if (err) {
|
|
||||||
reject(err);
|
|
||||||
}
|
}
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to overwrite user config on windows installer
|
if (isEnabled && !lStartup) {
|
||||||
function updateUserConfigWin() {
|
return symphonyAutoLauncher.disable();
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let userConfigPath = app.getPath('userData');
|
|
||||||
let globalConfigPath = path.join(__dirname, '..', '..', '..', 'config/Symphony.config');
|
|
||||||
|
|
||||||
childProcess.exec(`echo D|xcopy /y /e /s /c "${globalConfigPath}" "${userConfigPath}"`, {timeout: 60000}, (err) => {
|
|
||||||
if (err) {
|
|
||||||
reject(err);
|
|
||||||
}
|
}
|
||||||
resolve();
|
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for the url argument, processes it
|
||||||
|
* and creates the main window
|
||||||
|
*/
|
||||||
function getUrlAndCreateMainWindow() {
|
function getUrlAndCreateMainWindow() {
|
||||||
// for dev env allow passing url argument
|
// for dev env allow passing url argument
|
||||||
if (isDevEnv) {
|
if (isDevEnv) {
|
||||||
let url = getCmdLineArg(process.argv, '--url=')
|
let url = getCmdLineArg(process.argv, '--url=', false);
|
||||||
if (url) {
|
if (url) {
|
||||||
windowMgr.createMainWindow(url.substr(6));
|
windowMgr.createMainWindow(url.substr(6));
|
||||||
return;
|
return;
|
||||||
@ -211,12 +239,16 @@ function getUrlAndCreateMainWindow() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getConfigField('url')
|
getConfigField('url')
|
||||||
.then(createWin).catch(function (err) {
|
.then(createWin).catch(function(err) {
|
||||||
let title = 'Error loading configuration';
|
let title = 'Error loading configuration';
|
||||||
electron.dialog.showErrorBox(title, title + ': ' + err);
|
electron.dialog.showErrorBox(title, title + ': ' + err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a window
|
||||||
|
* @param urlFromConfig
|
||||||
|
*/
|
||||||
function createWin(urlFromConfig) {
|
function createWin(urlFromConfig) {
|
||||||
let protocol = '';
|
let protocol = '';
|
||||||
// add https protocol if none found.
|
// add https protocol if none found.
|
||||||
@ -224,7 +256,7 @@ function createWin(urlFromConfig) {
|
|||||||
if (!parsedUrl.protocol) {
|
if (!parsedUrl.protocol) {
|
||||||
protocol = 'https';
|
protocol = 'https';
|
||||||
}
|
}
|
||||||
var url = nodeURL.format({
|
let url = nodeURL.format({
|
||||||
protocol: protocol,
|
protocol: protocol,
|
||||||
slahes: true,
|
slahes: true,
|
||||||
pathname: parsedUrl.href
|
pathname: parsedUrl.href
|
||||||
@ -246,7 +278,7 @@ function processProtocolAction(argv) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let protocolUri = getCmdLineArg(argv, 'symphony://');
|
let protocolUri = getCmdLineArg(argv, 'symphony://', false);
|
||||||
|
|
||||||
if (protocolUri) {
|
if (protocolUri) {
|
||||||
|
|
||||||
@ -261,6 +293,10 @@ function processProtocolAction(argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a protocol action based on the current state of the app
|
||||||
|
* @param uri
|
||||||
|
*/
|
||||||
function handleProtocolAction(uri) {
|
function handleProtocolAction(uri) {
|
||||||
if (!isAppAlreadyOpen) {
|
if (!isAppAlreadyOpen) {
|
||||||
// app is opened by the protocol url, cache the protocol url to be used later
|
// app is opened by the protocol url, cache the protocol url to be used later
|
||||||
@ -269,4 +305,4 @@ function handleProtocolAction(uri) {
|
|||||||
// app is already open, so, just trigger the protocol action method
|
// app is already open, so, just trigger the protocol action method
|
||||||
protocolHandler.processProtocolAction(uri);
|
protocolHandler.processProtocolAction(uri);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -9,7 +9,7 @@ const electron = require('electron');
|
|||||||
const windowMgr = require('./windowMgr.js');
|
const windowMgr = require('./windowMgr.js');
|
||||||
const log = require('./log.js');
|
const log = require('./log.js');
|
||||||
const logLevels = require('./enums/logLevels');
|
const logLevels = require('./enums/logLevels');
|
||||||
const activityDetection = require('./activityDetection/activityDetection');
|
const activityDetection = require('./activityDetection');
|
||||||
const badgeCount = require('./badgeCount.js');
|
const badgeCount = require('./badgeCount.js');
|
||||||
const protocolHandler = require('./protocolHandler');
|
const protocolHandler = require('./protocolHandler');
|
||||||
const configureNotification = require('./notify/settings/configure-notification-position');
|
const configureNotification = require('./notify/settings/configure-notification-position');
|
||||||
@ -30,7 +30,7 @@ function isValidWindow(event) {
|
|||||||
if (!checkValidWindow) {
|
if (!checkValidWindow) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
var result = false;
|
let result = false;
|
||||||
if (event && event.sender) {
|
if (event && event.sender) {
|
||||||
// validate that event sender is from window we created
|
// validate that event sender is from window we created
|
||||||
const browserWin = electron.BrowserWindow.fromWebContents(event.sender);
|
const browserWin = electron.BrowserWindow.fromWebContents(event.sender);
|
||||||
@ -107,7 +107,7 @@ electron.ipcMain.on(apiName, (event, arg) => {
|
|||||||
|
|
||||||
// expose these methods primarily for testing...
|
// expose these methods primarily for testing...
|
||||||
module.exports = {
|
module.exports = {
|
||||||
shouldCheckValidWindow: function (shouldCheck) {
|
shouldCheckValidWindow: function(shouldCheck) {
|
||||||
checkValidWindow = shouldCheck;
|
checkValidWindow = shouldCheck;
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -1,14 +1,17 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const log = require('./log.js');
|
const log = require('./log.js');
|
||||||
const logLevels = require('./enums/logLevels.js')
|
const logLevels = require('./enums/logLevels.js');
|
||||||
|
|
||||||
// once a minute
|
// once a minute
|
||||||
setInterval(gatherMemory, 1000 * 60);
|
setInterval(gatherMemory, 1000 * 60);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gathers system memory and logs it to the remote system
|
||||||
|
*/
|
||||||
function gatherMemory() {
|
function gatherMemory() {
|
||||||
var memory = process.getProcessMemoryInfo();
|
let memory = process.getProcessMemoryInfo();
|
||||||
var details =
|
let details =
|
||||||
'workingSetSize: ' + memory.workingSetSize +
|
'workingSetSize: ' + memory.workingSetSize +
|
||||||
' peakWorkingSetSize: ' + memory.peakWorkingSetSize +
|
' peakWorkingSetSize: ' + memory.peakWorkingSetSize +
|
||||||
' privatesBytes: ' + memory.privatesBytes +
|
' privatesBytes: ' + memory.privatesBytes +
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const electron = require('electron');
|
const electron = require('electron');
|
||||||
const { getConfigField, updateConfigField } = require('../config.js');
|
const { updateConfigField, getMultipleConfigField } = require('../config.js');
|
||||||
const AutoLaunch = require('auto-launch');
|
const AutoLaunch = require('auto-launch');
|
||||||
const isMac = require('../utils/misc.js').isMac;
|
const isMac = require('../utils/misc.js').isMac;
|
||||||
const log = require('../log.js');
|
const log = require('../log.js');
|
||||||
const logLevels = require('../enums/logLevels.js');
|
const logLevels = require('../enums/logLevels.js');
|
||||||
const eventEmitter = require('../eventEmitter');
|
const eventEmitter = require('../eventEmitter');
|
||||||
|
const aboutApp = require('../aboutApp');
|
||||||
|
|
||||||
var minimizeOnClose = false;
|
let minimizeOnClose = false;
|
||||||
var launchOnStartup = false;
|
let launchOnStartup = false;
|
||||||
var isAlwaysOnTop = false;
|
let isAlwaysOnTop = false;
|
||||||
|
|
||||||
setCheckboxValues();
|
|
||||||
|
|
||||||
let symphonyAutoLauncher;
|
let symphonyAutoLauncher;
|
||||||
|
|
||||||
@ -31,10 +30,9 @@ if (isMac) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const template = [
|
const template = [{
|
||||||
{
|
label: 'Edit',
|
||||||
label: 'Edit',
|
submenu: [
|
||||||
submenu: [
|
|
||||||
{ role: 'undo' },
|
{ role: 'undo' },
|
||||||
{ role: 'redo' },
|
{ role: 'redo' },
|
||||||
{ type: 'separator' },
|
{ type: 'separator' },
|
||||||
@ -44,265 +42,272 @@ const template = [
|
|||||||
{ role: 'pasteandmatchstyle' },
|
{ role: 'pasteandmatchstyle' },
|
||||||
{ role: 'delete' },
|
{ role: 'delete' },
|
||||||
{ role: 'selectall' }
|
{ role: 'selectall' }
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'View',
|
||||||
|
submenu: [{
|
||||||
|
label: 'Reload',
|
||||||
|
accelerator: 'CmdOrCtrl+R',
|
||||||
|
click(item, focusedWindow) {
|
||||||
|
if (focusedWindow) {
|
||||||
|
focusedWindow.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'View',
|
label: 'Toggle Developer Tools',
|
||||||
submenu: [
|
accelerator: isMac ? 'Alt+Command+I' : 'Ctrl+Shift+I',
|
||||||
{
|
click(item, focusedWindow) {
|
||||||
label: 'Reload',
|
if (focusedWindow) {
|
||||||
accelerator: 'CmdOrCtrl+R',
|
focusedWindow.webContents.toggleDevTools();
|
||||||
click (item, focusedWindow) {
|
|
||||||
if (focusedWindow) {
|
|
||||||
focusedWindow.reload();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Toggle Developer Tools',
|
|
||||||
accelerator: isMac ? 'Alt+Command+I' : 'Ctrl+Shift+I',
|
|
||||||
click (item, focusedWindow) {
|
|
||||||
if (focusedWindow) {
|
|
||||||
focusedWindow.webContents.toggleDevTools();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'separator'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
role: 'resetzoom'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
role: 'zoomin'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
role: 'zoomout'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'separator'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
role: 'togglefullscreen'
|
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: 'window',
|
label: 'Open Crashes Directory',
|
||||||
submenu: [
|
click() {
|
||||||
{
|
const crashesDirectory = electron.crashReporter.getCrashesDirectory() + '/completed';
|
||||||
role: 'minimize'
|
electron.shell.showItemInFolder(crashesDirectory);
|
||||||
},
|
}
|
||||||
{
|
|
||||||
role: 'close'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: 'help',
|
type: 'separator'
|
||||||
submenu: [
|
},
|
||||||
{
|
{
|
||||||
label: 'Learn More',
|
role: 'resetzoom'
|
||||||
click () { electron.shell.openExternal('https://www.symphony.com') }
|
},
|
||||||
}
|
{
|
||||||
]
|
role: 'zoomin'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: 'zoomout'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'separator'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: 'togglefullscreen'
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: 'window',
|
||||||
|
submenu: [{
|
||||||
|
role: 'minimize'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: 'close'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: 'help',
|
||||||
|
submenu: [
|
||||||
|
{
|
||||||
|
label: 'Learn More',
|
||||||
|
click() { electron.shell.openExternal('https://www.symphony.com'); }
|
||||||
|
}]
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
function getTemplate(app) {
|
function getTemplate(app) {
|
||||||
if (isMac && template[0].label !== app.getName()) {
|
if (isMac && template[0].label !== app.getName()) {
|
||||||
template.unshift({
|
template.unshift({
|
||||||
label: app.getName(),
|
label: app.getName(),
|
||||||
submenu: [
|
submenu: [{
|
||||||
{
|
role: 'about'
|
||||||
role: 'about'
|
},
|
||||||
},
|
{
|
||||||
{
|
type: 'separator'
|
||||||
type: 'separator'
|
},
|
||||||
},
|
{
|
||||||
{
|
role: 'services',
|
||||||
role: 'services',
|
submenu: []
|
||||||
submenu: []
|
},
|
||||||
},
|
{
|
||||||
{
|
type: 'separator'
|
||||||
type: 'separator'
|
},
|
||||||
},
|
{
|
||||||
{
|
role: 'hide'
|
||||||
role: 'hide'
|
},
|
||||||
},
|
{
|
||||||
{
|
role: 'hideothers'
|
||||||
role: 'hideothers'
|
},
|
||||||
},
|
{
|
||||||
{
|
role: 'unhide'
|
||||||
role: 'unhide'
|
},
|
||||||
},
|
{
|
||||||
{
|
type: 'separator'
|
||||||
type: 'separator'
|
},
|
||||||
},
|
{
|
||||||
{
|
role: 'quit'
|
||||||
role: 'quit'
|
}
|
||||||
}
|
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
// Edit menu.
|
// Edit menu.
|
||||||
template[1].submenu.push(
|
template[1].submenu.push({
|
||||||
{
|
type: 'separator'
|
||||||
type: 'separator'
|
}, {
|
||||||
|
label: 'Speech',
|
||||||
|
submenu: [{
|
||||||
|
role: 'startspeaking'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Speech',
|
role: 'stopspeaking'
|
||||||
submenu: [
|
|
||||||
{
|
|
||||||
role: 'startspeaking'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
role: 'stopspeaking'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
)
|
]
|
||||||
// Window menu.
|
});
|
||||||
template[3].submenu = [
|
// Window menu.
|
||||||
{
|
template[3].submenu = [{
|
||||||
label: 'Close',
|
label: 'Close',
|
||||||
accelerator: 'CmdOrCtrl+W',
|
accelerator: 'CmdOrCtrl+W',
|
||||||
role: 'close'
|
role: 'close'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Minimize',
|
label: 'Minimize',
|
||||||
accelerator: 'CmdOrCtrl+M',
|
accelerator: 'CmdOrCtrl+M',
|
||||||
role: 'minimize'
|
role: 'minimize'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Zoom',
|
label: 'Zoom',
|
||||||
role: 'zoom'
|
role: 'zoom'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'separator'
|
type: 'separator'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Bring All to Front',
|
label: 'Bring All to Front',
|
||||||
role: 'front'
|
role: 'front'
|
||||||
}
|
}
|
||||||
]
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
var index = 2;
|
let index = 2;
|
||||||
if (isMac && template[0].label !== app.getName()){
|
if (isMac && template[0].label !== app.getName()) {
|
||||||
index = 3;
|
index = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Window menu -> launchOnStartup.
|
// Window menu -> launchOnStartup.
|
||||||
template[index].submenu.push(
|
template[index].submenu.push({
|
||||||
{
|
label: 'Auto Launch On Startup',
|
||||||
label: 'Auto Launch On Startup',
|
type: 'checkbox',
|
||||||
type: 'checkbox',
|
checked: launchOnStartup,
|
||||||
checked: launchOnStartup,
|
click: function(item) {
|
||||||
click: function (item) {
|
if (item.checked) {
|
||||||
if (item.checked){
|
symphonyAutoLauncher.enable()
|
||||||
symphonyAutoLauncher.enable()
|
.catch(function(err) {
|
||||||
.catch(function (err) {
|
let title = 'Error setting AutoLaunch configuration';
|
||||||
let title = 'Error setting AutoLaunch configuration';
|
log.send(logLevels.ERROR, 'MenuTemplate: ' + title + ': auto launch error ' + err);
|
||||||
log.send(logLevels.ERROR, 'MenuTemplate: ' + title + ': auto launch error ' + err);
|
electron.dialog.showErrorBox(title, title + ': ' + err);
|
||||||
electron.dialog.showErrorBox(title, title + ': ' + err);
|
});
|
||||||
});
|
} else {
|
||||||
} else {
|
symphonyAutoLauncher.disable()
|
||||||
symphonyAutoLauncher.disable()
|
.catch(function(err) {
|
||||||
.catch(function (err) {
|
let title = 'Error setting AutoLaunch configuration';
|
||||||
let title = 'Error setting AutoLaunch configuration';
|
log.send(logLevels.ERROR, 'MenuTemplate: ' + title + ': auto launch error ' + err);
|
||||||
log.send(logLevels.ERROR, 'MenuTemplate: ' + title + ': auto launch error ' + err);
|
electron.dialog.showErrorBox(title, title + ': ' + err);
|
||||||
electron.dialog.showErrorBox(title, title + ': ' + err);
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
launchOnStartup = item.checked;
|
|
||||||
updateConfigField('launchOnStartup', launchOnStartup);
|
|
||||||
}
|
}
|
||||||
|
launchOnStartup = item.checked;
|
||||||
|
updateConfigField('launchOnStartup', launchOnStartup);
|
||||||
}
|
}
|
||||||
)
|
});
|
||||||
|
|
||||||
// Window menu -> alwaysOnTop.
|
// Window menu -> alwaysOnTop.
|
||||||
template[index].submenu.push(
|
template[index].submenu.push({
|
||||||
{
|
label: 'Always on top',
|
||||||
label: 'Always on top',
|
type: 'checkbox',
|
||||||
type: 'checkbox',
|
checked: isAlwaysOnTop,
|
||||||
checked: isAlwaysOnTop,
|
click: (item) => {
|
||||||
click: (item) => {
|
isAlwaysOnTop = item.checked;
|
||||||
isAlwaysOnTop = item.checked;
|
eventEmitter.emit('isAlwaysOnTop', isAlwaysOnTop);
|
||||||
eventEmitter.emit('isAlwaysOnTop', isAlwaysOnTop);
|
updateConfigField('alwaysOnTop', isAlwaysOnTop);
|
||||||
updateConfigField('alwaysOnTop', isAlwaysOnTop);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
});
|
||||||
|
|
||||||
// Window menu -> minimizeOnClose.
|
// Window menu -> minimizeOnClose.
|
||||||
// ToDo: Add behavior on Close.
|
// ToDo: Add behavior on Close.
|
||||||
template[index].submenu.push(
|
template[index].submenu.push({
|
||||||
{
|
label: 'Minimize on Close',
|
||||||
label: 'Minimize on Close',
|
type: 'checkbox',
|
||||||
type: 'checkbox',
|
checked: minimizeOnClose,
|
||||||
checked: minimizeOnClose,
|
click: function(item) {
|
||||||
click: function (item) {
|
minimizeOnClose = item.checked;
|
||||||
minimizeOnClose = item.checked;
|
updateConfigField('minimizeOnClose', minimizeOnClose);
|
||||||
updateConfigField('minimizeOnClose', minimizeOnClose);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
});
|
||||||
|
|
||||||
if (!isMac){
|
if (!isMac) {
|
||||||
template[index].submenu.push(
|
template[index].submenu.push({
|
||||||
{
|
label: 'Quit Symphony',
|
||||||
label: 'Quit Symphony',
|
click: function() {
|
||||||
click: function () {
|
app.quit();
|
||||||
app.quit();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
});
|
||||||
|
|
||||||
|
// This adds About Symphony under help menu for windows
|
||||||
|
template[3].submenu.push({
|
||||||
|
label: 'About Symphony',
|
||||||
|
click(focusedWindow) {
|
||||||
|
let windowName = focusedWindow ? focusedWindow.name : '';
|
||||||
|
aboutApp.openAboutWindow(windowName);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setCheckboxValues(){
|
/**
|
||||||
getConfigField('minimizeOnClose').then(function(mClose) {
|
* Sets the checkbox values for different menu items
|
||||||
minimizeOnClose = mClose;
|
* based on configuration
|
||||||
}).catch(function (err){
|
*/
|
||||||
let title = 'Error loading configuration';
|
function setCheckboxValues() {
|
||||||
log.send(logLevels.ERROR, 'MenuTemplate: error getting config field minimizeOnClose, error: ' + err);
|
return new Promise((resolve) => {
|
||||||
electron.dialog.showErrorBox(title, title + ': ' + err);
|
/**
|
||||||
|
* Method that reads multiple config fields
|
||||||
|
*/
|
||||||
|
getMultipleConfigField(['minimizeOnClose', 'launchOnStartup', 'alwaysOnTop', 'notificationSettings'])
|
||||||
|
.then(function (configData) {
|
||||||
|
for (let key in configData) {
|
||||||
|
if (configData.hasOwnProperty(key)) { // eslint-disable-line no-prototype-builtins
|
||||||
|
switch (key) {
|
||||||
|
case 'minimizeOnClose':
|
||||||
|
minimizeOnClose = configData[key];
|
||||||
|
break;
|
||||||
|
case 'launchOnStartup':
|
||||||
|
launchOnStartup = configData[key];
|
||||||
|
break;
|
||||||
|
case 'alwaysOnTop':
|
||||||
|
isAlwaysOnTop = configData[key];
|
||||||
|
eventEmitter.emit('isAlwaysOnTop', configData[key]);
|
||||||
|
break;
|
||||||
|
case 'notificationSettings':
|
||||||
|
eventEmitter.emit('notificationSettings', configData[key]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resolve();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
let title = 'Error loading configuration';
|
||||||
|
log.send(logLevels.ERROR, 'MenuTemplate: error reading configuration fields, error: ' + err);
|
||||||
|
electron.dialog.showErrorBox(title, title + ': ' + err);
|
||||||
|
return resolve();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
getConfigField('launchOnStartup').then(function(lStartup) {
|
|
||||||
launchOnStartup = lStartup;
|
|
||||||
}).catch(function (err){
|
|
||||||
let title = 'Error loading configuration';
|
|
||||||
log.send(logLevels.ERROR, 'MenuTemplate: error getting config field launchOnStartup, error: ' + err);
|
|
||||||
electron.dialog.showErrorBox(title, title + ': ' + err);
|
|
||||||
});
|
|
||||||
|
|
||||||
getConfigField('alwaysOnTop').then(function(mAlwaysOnTop) {
|
|
||||||
isAlwaysOnTop = mAlwaysOnTop;
|
|
||||||
eventEmitter.emit('isAlwaysOnTop', isAlwaysOnTop);
|
|
||||||
}).catch(function (err){
|
|
||||||
let title = 'Error loading configuration';
|
|
||||||
log.send(logLevels.ERROR, 'MenuTemplate: error getting config field alwaysOnTop, error: ' + err);
|
|
||||||
electron.dialog.showErrorBox(title, title + ': ' + err);
|
|
||||||
});
|
|
||||||
|
|
||||||
getConfigField('notificationSettings').then(function(notfObject) {
|
|
||||||
eventEmitter.emit('notificationSettings', notfObject);
|
|
||||||
}).catch(function (err){
|
|
||||||
let title = 'Error loading configuration';
|
|
||||||
log.send(logLevels.ERROR, 'MenuTemplate: error getting config field notificationSettings, error: ' + err);
|
|
||||||
electron.dialog.showErrorBox(title, title + ': ' + err);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMinimizeOnClose(){
|
function getMinimizeOnClose() {
|
||||||
return minimizeOnClose;
|
return minimizeOnClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getTemplate : getTemplate,
|
getTemplate: getTemplate,
|
||||||
getMinimizeOnClose : getMinimizeOnClose
|
getMinimizeOnClose: getMinimizeOnClose,
|
||||||
|
setCheckboxValues: setCheckboxValues
|
||||||
};
|
};
|
@ -3,13 +3,21 @@
|
|||||||
const log = require('../log.js');
|
const log = require('../log.js');
|
||||||
const logLevels = require('../enums/logLevels.js');
|
const logLevels = require('../enums/logLevels.js');
|
||||||
|
|
||||||
// One animation at a time
|
/**
|
||||||
|
* Manages one animation at a time
|
||||||
|
* @param options
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
const AnimationQueue = function(options) {
|
const AnimationQueue = function(options) {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.queue = [];
|
this.queue = [];
|
||||||
this.running = false;
|
this.running = false;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes each animation to a queue
|
||||||
|
* @param object
|
||||||
|
*/
|
||||||
AnimationQueue.prototype.push = function(object) {
|
AnimationQueue.prototype.push = function(object) {
|
||||||
if (this.running) {
|
if (this.running) {
|
||||||
this.queue.push(object);
|
this.queue.push(object);
|
||||||
@ -17,8 +25,12 @@ AnimationQueue.prototype.push = function(object) {
|
|||||||
this.running = true;
|
this.running = true;
|
||||||
setTimeout(this.animate.bind(this, object), 0);
|
setTimeout(this.animate.bind(this, object), 0);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Animates an animation that is part of the queue
|
||||||
|
* @param object
|
||||||
|
*/
|
||||||
AnimationQueue.prototype.animate = function(object) {
|
AnimationQueue.prototype.animate = function(object) {
|
||||||
object.func.apply(null, object.args)
|
object.func.apply(null, object.args)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
@ -37,10 +49,13 @@ AnimationQueue.prototype.animate = function(object) {
|
|||||||
' with stack trace:' + err.stack);
|
' with stack trace:' + err.stack);
|
||||||
/* eslint-enable no-console */
|
/* eslint-enable no-console */
|
||||||
})
|
})
|
||||||
}
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the queue
|
||||||
|
*/
|
||||||
AnimationQueue.prototype.clear = function() {
|
AnimationQueue.prototype.clear = function() {
|
||||||
this.queue = [];
|
this.queue = [];
|
||||||
}
|
};
|
||||||
|
|
||||||
module.exports = AnimationQueue;
|
module.exports = AnimationQueue;
|
||||||
|
BIN
js/notify/assets/symphony-logo-black.png
Normal file
BIN
js/notify/assets/symphony-logo-black.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
js/notify/assets/symphony-logo-white.png
Normal file
BIN
js/notify/assets/symphony-logo-white.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
@ -1,4 +1,4 @@
|
|||||||
'use strict'
|
'use strict';
|
||||||
|
|
||||||
//
|
//
|
||||||
// BrowserWindow preload script use to create notifications window for
|
// BrowserWindow preload script use to create notifications window for
|
||||||
@ -9,37 +9,54 @@
|
|||||||
const electron = require('electron');
|
const electron = require('electron');
|
||||||
const ipc = electron.ipcRenderer;
|
const ipc = electron.ipcRenderer;
|
||||||
|
|
||||||
|
const whiteColorRegExp = new RegExp(/^(?:white|#fff(?:fff)?|rgba?\(\s*255\s*,\s*255\s*,\s*255\s*(?:,\s*1\s*)?\))$/i);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets style for a notification
|
||||||
|
* @param config
|
||||||
|
*/
|
||||||
function setStyle(config) {
|
function setStyle(config) {
|
||||||
// Style it
|
// Style it
|
||||||
let notiDoc = window.document;
|
let notiDoc = window.document;
|
||||||
let container = notiDoc.getElementById('container');
|
let container = notiDoc.getElementById('container');
|
||||||
let header = notiDoc.getElementById('header');
|
let header = notiDoc.getElementById('header');
|
||||||
let image = notiDoc.getElementById('image');
|
let image = notiDoc.getElementById('image');
|
||||||
|
let logo = notiDoc.getElementById('symphony-logo');
|
||||||
let title = notiDoc.getElementById('title');
|
let title = notiDoc.getElementById('title');
|
||||||
|
let pod = notiDoc.getElementById('pod');
|
||||||
let message = notiDoc.getElementById('message');
|
let message = notiDoc.getElementById('message');
|
||||||
let close = notiDoc.getElementById('close');
|
let close = notiDoc.getElementById('close');
|
||||||
|
|
||||||
// Default style
|
// Default style
|
||||||
setStyleOnDomElement(config.defaultStyleContainer, container)
|
setStyleOnDomElement(config.defaultStyleContainer, container);
|
||||||
|
|
||||||
let style = {
|
let style = {
|
||||||
height: config.height,
|
height: config.height,
|
||||||
width: config.width,
|
width: config.width,
|
||||||
borderRadius: config.borderRadius + 'px'
|
borderRadius: config.borderRadius + 'px'
|
||||||
}
|
};
|
||||||
setStyleOnDomElement(style, container)
|
setStyleOnDomElement(style, container);
|
||||||
|
|
||||||
setStyleOnDomElement(config.defaultStyleHeader, header);
|
setStyleOnDomElement(config.defaultStyleHeader, header);
|
||||||
|
|
||||||
setStyleOnDomElement(config.defaultStyleImage, image);
|
setStyleOnDomElement(config.defaultStyleImage, image);
|
||||||
|
|
||||||
|
setStyleOnDomElement(config.defaultStyleLogo, logo);
|
||||||
|
|
||||||
setStyleOnDomElement(config.defaultStyleTitle, title);
|
setStyleOnDomElement(config.defaultStyleTitle, title);
|
||||||
|
|
||||||
|
setStyleOnDomElement(config.defaultStylePod, pod);
|
||||||
|
|
||||||
setStyleOnDomElement(config.defaultStyleText, message);
|
setStyleOnDomElement(config.defaultStyleText, message);
|
||||||
|
|
||||||
setStyleOnDomElement(config.defaultStyleClose, close);
|
setStyleOnDomElement(config.defaultStyleClose, close);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets contents for a notification
|
||||||
|
* @param event
|
||||||
|
* @param notificationObj
|
||||||
|
*/
|
||||||
function setContents(event, notificationObj) {
|
function setContents(event, notificationObj) {
|
||||||
// sound
|
// sound
|
||||||
if (notificationObj.sound) {
|
if (notificationObj.sound) {
|
||||||
@ -49,7 +66,7 @@ function setContents(event, notificationObj) {
|
|||||||
// Won't check remote files e.g. http://
|
// Won't check remote files e.g. http://
|
||||||
if (notificationObj.sound.match(/^file:/) !== null
|
if (notificationObj.sound.match(/^file:/) !== null
|
||||||
|| notificationObj.sound.match(/^\//) !== null) {
|
|| notificationObj.sound.match(/^\//) !== null) {
|
||||||
let audio = new window.Audio(notificationObj.sound)
|
let audio = new window.Audio(notificationObj.sound);
|
||||||
audio.play()
|
audio.play()
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -66,6 +83,20 @@ function setContents(event, notificationObj) {
|
|||||||
|
|
||||||
if (notificationObj.color) {
|
if (notificationObj.color) {
|
||||||
container.style.backgroundColor = notificationObj.color;
|
container.style.backgroundColor = notificationObj.color;
|
||||||
|
let logo = notiDoc.getElementById('symphony-logo');
|
||||||
|
|
||||||
|
if (notificationObj.color.match(whiteColorRegExp)) {
|
||||||
|
logo.src = './assets/symphony-logo-black.png';
|
||||||
|
} else {
|
||||||
|
let title = notiDoc.getElementById('title');
|
||||||
|
let pod = notiDoc.getElementById('pod');
|
||||||
|
let message = notiDoc.getElementById('message');
|
||||||
|
|
||||||
|
message.style.color = '#ffffff';
|
||||||
|
title.style.color = '#ffffff';
|
||||||
|
pod.style.color = notificationObj.color;
|
||||||
|
logo.src = './assets/symphony-logo-white.png';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notificationObj.flash) {
|
if (notificationObj.flash) {
|
||||||
@ -102,15 +133,20 @@ function setContents(event, notificationObj) {
|
|||||||
// note: use onclick because we only want one handler, for case
|
// note: use onclick because we only want one handler, for case
|
||||||
// when content gets overwritten by notf with same tag
|
// when content gets overwritten by notf with same tag
|
||||||
closeButton.onclick = function(clickEvent) {
|
closeButton.onclick = function(clickEvent) {
|
||||||
clickEvent.stopPropagation()
|
clickEvent.stopPropagation();
|
||||||
ipc.send('electron-notify-close', winId, notificationObj)
|
ipc.send('electron-notify-close', winId, notificationObj)
|
||||||
}
|
};
|
||||||
|
|
||||||
container.onclick = function() {
|
container.onclick = function() {
|
||||||
ipc.send('electron-notify-click', winId, notificationObj);
|
ipc.send('electron-notify-click', winId, notificationObj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets style on a notification for a DOM element
|
||||||
|
* @param styleObj
|
||||||
|
* @param domElement
|
||||||
|
*/
|
||||||
function setStyleOnDomElement(styleObj, domElement) {
|
function setStyleOnDomElement(styleObj, domElement) {
|
||||||
try {
|
try {
|
||||||
let styleAttr = Object.keys(styleObj);
|
let styleAttr = Object.keys(styleObj);
|
||||||
@ -124,22 +160,30 @@ function setStyleOnDomElement(styleObj, domElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the config
|
||||||
|
* @param event
|
||||||
|
* @param conf
|
||||||
|
*/
|
||||||
function loadConfig(event, conf) {
|
function loadConfig(event, conf) {
|
||||||
setStyle(conf || {})
|
setStyle(conf || {})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the notification window
|
||||||
|
*/
|
||||||
function reset() {
|
function reset() {
|
||||||
let notiDoc = window.document
|
let notiDoc = window.document;
|
||||||
let container = notiDoc.getElementById('container')
|
let container = notiDoc.getElementById('container');
|
||||||
let closeButton = notiDoc.getElementById('close')
|
let closeButton = notiDoc.getElementById('close');
|
||||||
|
|
||||||
// Remove event listener
|
// Remove event listener
|
||||||
let newContainer = container.cloneNode(true)
|
let newContainer = container.cloneNode(true);
|
||||||
container.parentNode.replaceChild(newContainer, container)
|
container.parentNode.replaceChild(newContainer, container);
|
||||||
let newCloseButton = closeButton.cloneNode(true)
|
let newCloseButton = closeButton.cloneNode(true);
|
||||||
closeButton.parentNode.replaceChild(newCloseButton, closeButton)
|
closeButton.parentNode.replaceChild(newCloseButton, closeButton)
|
||||||
}
|
}
|
||||||
|
|
||||||
ipc.on('electron-notify-set-contents', setContents)
|
ipc.on('electron-notify-set-contents', setContents);
|
||||||
ipc.on('electron-notify-load-config', loadConfig)
|
ipc.on('electron-notify-load-config', loadConfig);
|
||||||
ipc.on('electron-notify-reset', reset)
|
ipc.on('electron-notify-reset', reset);
|
||||||
|
@ -2,15 +2,21 @@
|
|||||||
<head></head>
|
<head></head>
|
||||||
<body style='margin:0; overflow: hidden; -webkit-user-select: none;'>
|
<body style='margin:0; overflow: hidden; -webkit-user-select: none;'>
|
||||||
<div id="container">
|
<div id="container">
|
||||||
<div id="header">
|
<div>
|
||||||
<img src="" id="image" />
|
<img src="" id="symphony-logo">
|
||||||
|
</div>
|
||||||
|
<div id="header">
|
||||||
<span id="title"></span>
|
<span id="title"></span>
|
||||||
|
<span id="pod"></span>
|
||||||
|
<span id="message"></span>
|
||||||
</div>
|
</div>
|
||||||
<p id="message"></p>
|
<div id="picture">
|
||||||
|
<img src="" id="image" style="border-radius: 4px" />
|
||||||
|
</div>
|
||||||
<div id="close">
|
<div id="close">
|
||||||
<svg fill="#000000" height="16" viewBox="0 0 24 24" width="16" xmlns="http://www.w3.org/2000/svg">
|
<svg fill="#000000" height="16" viewBox="0 0 24 24" width="16" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
|
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path>
|
||||||
<path d="M0 0h24v24H0z" fill="none"/>
|
<path d="M0 0h24v24H0z" fill="none"></path>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
'use strict'
|
'use strict';
|
||||||
//
|
//
|
||||||
// code here adapted from https://www.npmjs.com/package/electron-notify
|
// code here adapted from https://www.npmjs.com/package/electron-notify
|
||||||
// made following changes:
|
// made following changes:
|
||||||
@ -55,9 +55,9 @@ let config = {
|
|||||||
// corner to put notifications
|
// corner to put notifications
|
||||||
// upper-right, upper-left, lower-right, lower-left
|
// upper-right, upper-left, lower-right, lower-left
|
||||||
startCorner: 'upper-right',
|
startCorner: 'upper-right',
|
||||||
width: 300,
|
width: 380,
|
||||||
height: 80,
|
height: 70,
|
||||||
borderRadius: 2,
|
borderRadius: 5,
|
||||||
displayTime: 5000,
|
displayTime: 5000,
|
||||||
animationSteps: 5,
|
animationSteps: 5,
|
||||||
animationStepMs: 5,
|
animationStepMs: 5,
|
||||||
@ -67,63 +67,66 @@ let config = {
|
|||||||
defaultStyleContainer: {
|
defaultStyleContainer: {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
flexDirection: 'column',
|
|
||||||
backgroundColor: '#f0f0f0',
|
backgroundColor: '#f0f0f0',
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
padding: 10,
|
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
lineHeight: '15px',
|
lineHeight: '15px',
|
||||||
boxSizing: 'border-box'
|
boxSizing: 'border-box'
|
||||||
},
|
},
|
||||||
defaultStyleHeader: {
|
defaultStyleHeader: {
|
||||||
flex: '0 0 auto',
|
width: 245,
|
||||||
display: 'flex',
|
minWidth: 230,
|
||||||
flexDirection: 'row'
|
margin: "12px 10px"
|
||||||
},
|
},
|
||||||
defaultStyleImage: {
|
defaultStyleImage: {
|
||||||
flex: '0 0 auto',
|
height: 43,
|
||||||
overflow: 'hidden',
|
borderRadius: 4,
|
||||||
height: 30,
|
marginTop: 12,
|
||||||
width: 30,
|
width: 43
|
||||||
marginLeft: 0,
|
|
||||||
marginRight: 8
|
|
||||||
},
|
},
|
||||||
defaultStyleClose: {
|
defaultStyleClose: {
|
||||||
position: 'absolute',
|
|
||||||
top: 8,
|
|
||||||
right: 8,
|
|
||||||
width: 16,
|
width: 16,
|
||||||
height: 16,
|
height: 16,
|
||||||
|
margin: "10px 8px 0 8px",
|
||||||
opacity: 0.54,
|
opacity: 0.54,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: '#CCC'
|
color: '#CCC'
|
||||||
},
|
},
|
||||||
defaultStyleTitle: {
|
defaultStyleTitle: {
|
||||||
fontFamily: 'Arial',
|
fontFamily: 'sans-serif',
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight: 700,
|
fontWeight: 700,
|
||||||
opacity: 0.87,
|
color: '#4a4a4a',
|
||||||
marginRight: 10,
|
|
||||||
alignSelf: 'center',
|
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
display: '-webkit-box',
|
display: '-webkit-box',
|
||||||
webkitLineClamp: 2,
|
webkitLineClamp: 1,
|
||||||
|
webkitBoxOrient: 'vertical',
|
||||||
|
},
|
||||||
|
defaultStylePod: {
|
||||||
|
fontFamily: 'sans-serif',
|
||||||
|
fontSize: 11,
|
||||||
|
color: '#adadad',
|
||||||
|
overflow: 'hidden',
|
||||||
|
filter: 'brightness(70%)',
|
||||||
|
display: '-webkit-box',
|
||||||
|
webkitLineClamp: 1,
|
||||||
webkitBoxOrient: 'vertical',
|
webkitBoxOrient: 'vertical',
|
||||||
},
|
},
|
||||||
defaultStyleText: {
|
defaultStyleText: {
|
||||||
flex: '0 0 auto',
|
fontFamily: 'sans-serif',
|
||||||
fontFamily: 'Calibri',
|
fontSize: 12,
|
||||||
fontSize: 14,
|
color: '#4a4a4a',
|
||||||
fontWeight: 400,
|
marginTop: 12,
|
||||||
opacity: 0.87,
|
|
||||||
margin: 0,
|
|
||||||
marginTop: 4,
|
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
display: '-webkit-box',
|
display: '-webkit-box',
|
||||||
webkitLineClamp: 2,
|
webkitLineClamp: 1,
|
||||||
webkitBoxOrient: 'vertical',
|
webkitBoxOrient: 'vertical',
|
||||||
cursor: 'default'
|
cursor: 'default'
|
||||||
},
|
},
|
||||||
|
defaultStyleLogo: {
|
||||||
|
margin: "12px 0 0 -12px",
|
||||||
|
opacity: 0.6,
|
||||||
|
},
|
||||||
defaultWindow: {
|
defaultWindow: {
|
||||||
alwaysOnTop: true,
|
alwaysOnTop: true,
|
||||||
skipTaskbar: true,
|
skipTaskbar: true,
|
||||||
@ -138,13 +141,7 @@ let config = {
|
|||||||
nodeIntegration: isNodeEnv
|
nodeIntegration: isNodeEnv
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// function setConfig(customConfig) {
|
|
||||||
// Object.assign(customConfig, config);
|
|
||||||
//
|
|
||||||
// calcDimensions();
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (app.isReady()) {
|
if (app.isReady()) {
|
||||||
setup();
|
setup();
|
||||||
@ -152,7 +149,10 @@ if (app.isReady()) {
|
|||||||
app.on('ready', setup);
|
app.on('ready', setup);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method to update notification config
|
/**
|
||||||
|
* Method to update notification config
|
||||||
|
* @param customConfig
|
||||||
|
*/
|
||||||
function updateConfig(customConfig) {
|
function updateConfig(customConfig) {
|
||||||
// Fetching user preferred notification position from config
|
// Fetching user preferred notification position from config
|
||||||
if (customConfig.position) {
|
if (customConfig.position) {
|
||||||
@ -167,16 +167,23 @@ function updateConfig(customConfig) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to setup the notification configuration
|
||||||
|
*/
|
||||||
function setup() {
|
function setup() {
|
||||||
setupConfig();
|
setupConfig();
|
||||||
|
|
||||||
// if display added/removed/changed then re-run setup and remove all existing
|
// if display added/removed/changed then re-run setup and remove all existing
|
||||||
// notifications. ToDo: should reposition notifications rather than closing.
|
// notifications.
|
||||||
electron.screen.on('display-added', setupConfig);
|
electron.screen.on('display-added', setupConfig);
|
||||||
electron.screen.on('display-removed', setupConfig);
|
electron.screen.on('display-removed', setupConfig);
|
||||||
electron.screen.on('display-metrics-changed', setupConfig);
|
electron.screen.on('display-metrics-changed', setupConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to get the notification template path
|
||||||
|
* @returns {string|*}
|
||||||
|
*/
|
||||||
function getTemplatePath() {
|
function getTemplatePath() {
|
||||||
let templatePath = path.join(__dirname, 'electron-notify.html');
|
let templatePath = path.join(__dirname, 'electron-notify.html');
|
||||||
try {
|
try {
|
||||||
@ -188,12 +195,15 @@ function getTemplatePath() {
|
|||||||
return config.templatePath;
|
return config.templatePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the dimensions of the screen
|
||||||
|
*/
|
||||||
function calcDimensions() {
|
function calcDimensions() {
|
||||||
const vertSpaceBetweenNotf = 8;
|
const vertSpaceBetweenNotf = 8;
|
||||||
|
|
||||||
// Calc totalHeight & totalWidth
|
// Calc totalHeight & totalWidth
|
||||||
config.totalHeight = config.height + vertSpaceBetweenNotf;
|
config.totalHeight = config.height + vertSpaceBetweenNotf;
|
||||||
config.totalWidth = config.width
|
config.totalWidth = config.width;
|
||||||
|
|
||||||
let firstPosX, firstPosY;
|
let firstPosX, firstPosY;
|
||||||
switch (config.startCorner) {
|
switch (config.startCorner) {
|
||||||
@ -220,15 +230,17 @@ function calcDimensions() {
|
|||||||
config.firstPos = {
|
config.firstPos = {
|
||||||
x: firstPosX,
|
x: firstPosX,
|
||||||
y: firstPosY
|
y: firstPosY
|
||||||
}
|
};
|
||||||
|
|
||||||
// Set nextInsertPos
|
// Set nextInsertPos
|
||||||
nextInsertPos.x = config.firstPos.x
|
nextInsertPos.x = config.firstPos.x;
|
||||||
nextInsertPos.y = config.firstPos.y
|
nextInsertPos.y = config.firstPos.y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup the notification config
|
||||||
|
*/
|
||||||
function setupConfig() {
|
function setupConfig() {
|
||||||
closeAll();
|
|
||||||
|
|
||||||
// This feature only applies to windows
|
// This feature only applies to windows
|
||||||
if (!isMac) {
|
if (!isMac) {
|
||||||
@ -273,6 +285,11 @@ function setupConfig() {
|
|||||||
config.maxVisibleNotifications = config.maxVisibleNotifications > 5 ? 5 : config.maxVisibleNotifications;
|
config.maxVisibleNotifications = config.maxVisibleNotifications > 5 ? 5 : config.maxVisibleNotifications;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies the user
|
||||||
|
* @param notification
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
function notify(notification) {
|
function notify(notification) {
|
||||||
// Is it an object and only one argument?
|
// Is it an object and only one argument?
|
||||||
if (arguments.length === 1 && typeof notification === 'object') {
|
if (arguments.length === 1 && typeof notification === 'object') {
|
||||||
@ -283,17 +300,25 @@ function notify(notification) {
|
|||||||
animationQueue.push({
|
animationQueue.push({
|
||||||
func: showNotification,
|
func: showNotification,
|
||||||
args: [ notf ]
|
args: [ notf ]
|
||||||
})
|
});
|
||||||
return notf.id
|
return notf.id
|
||||||
}
|
}
|
||||||
log.send(logLevels.ERROR, 'electron-notify: ERROR notify() only accepts a single object with notification parameters.');
|
log.send(logLevels.ERROR, 'electron-notify: ERROR notify() only accepts a single object with notification parameters.');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment the notification
|
||||||
|
*/
|
||||||
function incrementId() {
|
function incrementId() {
|
||||||
latestID++;
|
latestID++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the notification to the user
|
||||||
|
* @param notificationObj
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
function showNotification(notificationObj) {
|
function showNotification(notificationObj) {
|
||||||
return new Promise(function(resolve) {
|
return new Promise(function(resolve) {
|
||||||
|
|
||||||
@ -349,7 +374,7 @@ function showNotification(notificationObj) {
|
|||||||
});
|
});
|
||||||
delete notificationWindow.electronNotifyOnCloseFunc;
|
delete notificationWindow.electronNotifyOnCloseFunc;
|
||||||
}
|
}
|
||||||
setNotificationContents(notificationWindow, notificationObj)
|
setNotificationContents(notificationWindow, notificationObj);
|
||||||
resolve();
|
resolve();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -361,8 +386,8 @@ function showNotification(notificationObj) {
|
|||||||
// Get inactiveWindow or create new:
|
// Get inactiveWindow or create new:
|
||||||
getWindow().then(function(notificationWindow) {
|
getWindow().then(function(notificationWindow) {
|
||||||
// Move window to position
|
// Move window to position
|
||||||
calcInsertPos()
|
calcInsertPos();
|
||||||
setWindowPosition(notificationWindow, nextInsertPos.x, nextInsertPos.y)
|
setWindowPosition(notificationWindow, nextInsertPos.x, nextInsertPos.y);
|
||||||
|
|
||||||
let updatedNotfWindow = setNotificationContents(notificationWindow, notificationObj);
|
let updatedNotfWindow = setNotificationContents(notificationWindow, notificationObj);
|
||||||
|
|
||||||
@ -378,6 +403,12 @@ function showNotification(notificationObj) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the HTML notification contents along with other options
|
||||||
|
* @param notfWindow
|
||||||
|
* @param notfObj
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
function setNotificationContents(notfWindow, notfObj) {
|
function setNotificationContents(notfWindow, notfObj) {
|
||||||
|
|
||||||
// Display time per notification basis.
|
// Display time per notification basis.
|
||||||
@ -387,7 +418,7 @@ function setNotificationContents(notfWindow, notfObj) {
|
|||||||
clearTimeout(notfWindow.displayTimer);
|
clearTimeout(notfWindow.displayTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
var updatedNotificationWindow = notfWindow;
|
const updatedNotificationWindow = notfWindow;
|
||||||
|
|
||||||
updatedNotificationWindow.notfyObj = notfObj;
|
updatedNotificationWindow.notfyObj = notfObj;
|
||||||
|
|
||||||
@ -437,7 +468,13 @@ function setNotificationContents(notfWindow, notfObj) {
|
|||||||
return updatedNotificationWindow;
|
return updatedNotificationWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close notification function
|
/**
|
||||||
|
* Closes the notification
|
||||||
|
* @param notificationWindow
|
||||||
|
* @param notificationObj
|
||||||
|
* @param getTimeoutId
|
||||||
|
* @returns {Function}
|
||||||
|
*/
|
||||||
function buildCloseNotification(notificationWindow, notificationObj, getTimeoutId) {
|
function buildCloseNotification(notificationWindow, notificationObj, getTimeoutId) {
|
||||||
return function(event) {
|
return function(event) {
|
||||||
if (closedNotifications[notificationObj.id]) {
|
if (closedNotifications[notificationObj.id]) {
|
||||||
@ -459,7 +496,7 @@ function buildCloseNotification(notificationWindow, notificationObj, getTimeoutI
|
|||||||
}
|
}
|
||||||
|
|
||||||
// reset content
|
// reset content
|
||||||
notificationWindow.webContents.send('electron-notify-reset')
|
notificationWindow.webContents.send('electron-notify-reset');
|
||||||
if (getTimeoutId && typeof getTimeoutId === 'function') {
|
if (getTimeoutId && typeof getTimeoutId === 'function') {
|
||||||
let timeoutId = getTimeoutId();
|
let timeoutId = getTimeoutId();
|
||||||
clearTimeout(timeoutId);
|
clearTimeout(timeoutId);
|
||||||
@ -480,8 +517,13 @@ function buildCloseNotification(notificationWindow, notificationObj, getTimeoutI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always add to animationQueue to prevent erros (e.g. notification
|
/**
|
||||||
// got closed while it was moving will produce an error)
|
* Adds an active notification the close notification queue
|
||||||
|
* Always add to animationQueue to prevent erros (e.g. notification
|
||||||
|
* got closed while it was moving will produce an error)
|
||||||
|
* @param closeFunc
|
||||||
|
* @returns {Function}
|
||||||
|
*/
|
||||||
function buildCloseNotificationSafely(closeFunc) {
|
function buildCloseNotificationSafely(closeFunc) {
|
||||||
return function(reason) {
|
return function(reason) {
|
||||||
animationQueue.push({
|
animationQueue.push({
|
||||||
@ -509,10 +551,10 @@ ipc.on('electron-notify-click', function (event, winId, notificationObj) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Checks for queued notifications and add them
|
* Checks for queued notifications and add them
|
||||||
* to AnimationQueue if possible
|
* to AnimationQueue if possible
|
||||||
*/
|
*/
|
||||||
function checkForQueuedNotifications() {
|
function checkForQueuedNotifications() {
|
||||||
if (notificationQueue.length > 0 &&
|
if (notificationQueue.length > 0 &&
|
||||||
activeNotifications.length < config.maxVisibleNotifications) {
|
activeNotifications.length < config.maxVisibleNotifications) {
|
||||||
@ -524,25 +566,25 @@ function checkForQueuedNotifications() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Moves the notifications one position down,
|
* Moves the notifications one position down,
|
||||||
* starting with notification at startPos
|
* starting with notification at startPos
|
||||||
*
|
* @param startPos
|
||||||
* @param {int} startPos
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
function moveOneDown(startPos) {
|
function moveOneDown(startPos) {
|
||||||
return new Promise(function(resolve) {
|
return new Promise(function(resolve) {
|
||||||
if (startPos >= activeNotifications || startPos === -1) {
|
if (startPos >= activeNotifications || startPos === -1) {
|
||||||
resolve()
|
resolve();
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Build array with index of affected notifications
|
// Build array with index of affected notifications
|
||||||
let notificationPosArray = []
|
let notificationPosArray = [];
|
||||||
for (let i = startPos; i < activeNotifications.length; i++) {
|
for (let i = startPos; i < activeNotifications.length; i++) {
|
||||||
notificationPosArray.push(i)
|
notificationPosArray.push(i)
|
||||||
}
|
}
|
||||||
// Start to animate all notifications at once or in parallel
|
// Start to animate all notifications at once or in parallel
|
||||||
let asyncFunc = asyncMap // Best performance
|
let asyncFunc = asyncMap; // Best performance
|
||||||
if (config.animateInParallel === false) {
|
if (config.animateInParallel === false) {
|
||||||
asyncFunc = asyncMapSeries // Sluggish
|
asyncFunc = asyncMapSeries // Sluggish
|
||||||
}
|
}
|
||||||
@ -552,6 +594,11 @@ function moveOneDown(startPos) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the notification animation
|
||||||
|
* @param i
|
||||||
|
* @param done
|
||||||
|
*/
|
||||||
function moveNotificationAnimation(i, done) {
|
function moveNotificationAnimation(i, done) {
|
||||||
// Get notification to move
|
// Get notification to move
|
||||||
let notificationWindow = activeNotifications[i];
|
let notificationWindow = activeNotifications[i];
|
||||||
@ -571,32 +618,38 @@ function moveNotificationAnimation(i, done) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get startPos, calc step size and start animationInterval
|
// Get startPos, calc step size and start animationInterval
|
||||||
let startY = notificationWindow.getPosition()[1]
|
let startY = notificationWindow.getPosition()[1];
|
||||||
let step = (newY - startY) / config.animationSteps
|
let step = (newY - startY) / config.animationSteps;
|
||||||
let curStep = 1
|
let curStep = 1;
|
||||||
let animationInterval = setInterval(function() {
|
let animationInterval = setInterval(function() {
|
||||||
// Abort condition
|
// Abort condition
|
||||||
if (curStep === config.animationSteps) {
|
if (curStep === config.animationSteps) {
|
||||||
setWindowPosition(notificationWindow, config.firstPos.x, newY);
|
setWindowPosition(notificationWindow, config.firstPos.x, newY);
|
||||||
clearInterval(animationInterval)
|
clearInterval(animationInterval);
|
||||||
done(null, 'done');
|
done(null, 'done');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Move one step down
|
// Move one step down
|
||||||
setWindowPosition(notificationWindow, config.firstPos.x, startY + curStep * step)
|
setWindowPosition(notificationWindow, config.firstPos.x, startY + curStep * step);
|
||||||
curStep++
|
curStep++
|
||||||
}, config.animationStepMs)
|
}, config.animationStepMs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the window's position
|
||||||
|
* @param browserWin
|
||||||
|
* @param posX
|
||||||
|
* @param posY
|
||||||
|
*/
|
||||||
function setWindowPosition(browserWin, posX, posY) {
|
function setWindowPosition(browserWin, posX, posY) {
|
||||||
if (!browserWin.isDestroyed()) {
|
if (!browserWin.isDestroyed()) {
|
||||||
browserWin.setPosition(parseInt(posX, 10), parseInt(posY, 10))
|
browserWin.setPosition(parseInt(posX, 10), parseInt(posY, 10))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Find next possible insert position (on top)
|
* Find next possible insert position (on top)
|
||||||
*/
|
*/
|
||||||
function calcInsertPos() {
|
function calcInsertPos() {
|
||||||
if (activeNotifications.length < config.maxVisibleNotifications) {
|
if (activeNotifications.length < config.maxVisibleNotifications) {
|
||||||
switch(config.startCorner) {
|
switch(config.startCorner) {
|
||||||
@ -614,64 +667,43 @@ function calcInsertPos() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Get a window to display a notification. Use inactiveWindows or
|
* Get a window to display a notification. Use inactiveWindows or
|
||||||
* create a new window
|
* create a new window
|
||||||
* @return {Window}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
function getWindow() {
|
function getWindow() {
|
||||||
return new Promise(function(resolve) {
|
return new Promise(function(resolve) {
|
||||||
let notificationWindow
|
let notificationWindow;
|
||||||
// Are there still inactiveWindows?
|
// Are there still inactiveWindows?
|
||||||
if (inactiveWindows.length > 0) {
|
if (inactiveWindows.length > 0) {
|
||||||
notificationWindow = inactiveWindows.pop()
|
notificationWindow = inactiveWindows.pop();
|
||||||
resolve(notificationWindow)
|
resolve(notificationWindow)
|
||||||
} else {
|
} else {
|
||||||
// Or create a new window
|
// Or create a new window
|
||||||
let windowProperties = config.defaultWindow
|
let windowProperties = config.defaultWindow;
|
||||||
windowProperties.width = config.width
|
windowProperties.width = config.width;
|
||||||
windowProperties.height = config.height
|
windowProperties.height = config.height;
|
||||||
notificationWindow = new BrowserWindow(windowProperties)
|
notificationWindow = new BrowserWindow(windowProperties);
|
||||||
notificationWindow.setVisibleOnAllWorkspaces(true)
|
notificationWindow.setVisibleOnAllWorkspaces(true);
|
||||||
notificationWindow.loadURL(getTemplatePath())
|
notificationWindow.loadURL(getTemplatePath());
|
||||||
notificationWindow.webContents.on('did-finish-load', function() {
|
notificationWindow.webContents.on('did-finish-load', function() {
|
||||||
// Done
|
// Done
|
||||||
notificationWindow.webContents.send('electron-notify-load-config', config)
|
notificationWindow.webContents.send('electron-notify-load-config', config);
|
||||||
resolve(notificationWindow)
|
resolve(notificationWindow)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeAll() {
|
|
||||||
// Clear out animation Queue and close windows
|
|
||||||
animationQueue.clear();
|
|
||||||
|
|
||||||
activeNotifications.forEach(function(window) {
|
|
||||||
if (window.displayTimer) {
|
|
||||||
clearTimeout(window.displayTimer);
|
|
||||||
}
|
|
||||||
if (window.electronNotifyOnCloseFunc) {
|
|
||||||
// ToDo: fix this: shouldn't delete method on arg
|
|
||||||
/* eslint-disable */
|
|
||||||
delete window.electronNotifyOnCloseFunc;
|
|
||||||
/* eslint-enable */
|
|
||||||
}
|
|
||||||
window.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
cleanUpInactiveWindow();
|
|
||||||
|
|
||||||
// Reset certain vars
|
|
||||||
nextInsertPos = {};
|
|
||||||
activeNotifications = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
/* once a minute, remove inactive windows to free up memory used.
|
* Once a minute, remove inactive windows to free up memory used.
|
||||||
*/
|
*/
|
||||||
setInterval(cleanUpInactiveWindow, 60000);
|
setInterval(cleanUpInactiveWindow, 60000);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleans up inactive windows
|
||||||
|
*/
|
||||||
function cleanUpInactiveWindow() {
|
function cleanUpInactiveWindow() {
|
||||||
inactiveWindows.forEach(function(window) {
|
inactiveWindows.forEach(function(window) {
|
||||||
window.close();
|
window.close();
|
||||||
@ -679,6 +711,6 @@ function cleanUpInactiveWindow() {
|
|||||||
inactiveWindows = [];
|
inactiveWindows = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.notify = notify
|
module.exports.notify = notify;
|
||||||
module.exports.updateConfig = updateConfig
|
module.exports.updateConfig = updateConfig;
|
||||||
module.exports.reset = setupConfig
|
module.exports.reset = setupConfig;
|
||||||
|
@ -51,6 +51,10 @@ class Notify {
|
|||||||
|
|
||||||
this._data = options.data || null;
|
this._data = options.data || null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles on show event
|
||||||
|
* @param arg
|
||||||
|
*/
|
||||||
function onShow(arg) {
|
function onShow(arg) {
|
||||||
if (arg.id === this._id) {
|
if (arg.id === this._id) {
|
||||||
log.send(logLevels.INFO, 'showing notification, id=' + this._id);
|
log.send(logLevels.INFO, 'showing notification, id=' + this._id);
|
||||||
@ -61,6 +65,10 @@ class Notify {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles on click event
|
||||||
|
* @param arg
|
||||||
|
*/
|
||||||
function onClick(arg) {
|
function onClick(arg) {
|
||||||
if (arg.id === this._id) {
|
if (arg.id === this._id) {
|
||||||
log.send(logLevels.INFO, 'clicking notification, id=' + this._id);
|
log.send(logLevels.INFO, 'clicking notification, id=' + this._id);
|
||||||
@ -70,6 +78,10 @@ class Notify {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles on close event
|
||||||
|
* @param arg
|
||||||
|
*/
|
||||||
function onClose(arg) {
|
function onClose(arg) {
|
||||||
if (arg.id === this._id || arg.event === 'close-all') {
|
if (arg.id === this._id || arg.event === 'close-all') {
|
||||||
log.send(logLevels.INFO, 'closing notification, id=' + this._id);
|
log.send(logLevels.INFO, 'closing notification, id=' + this._id);
|
||||||
@ -80,6 +92,10 @@ class Notify {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles on error event
|
||||||
|
* @param arg
|
||||||
|
*/
|
||||||
function onError(arg) {
|
function onError(arg) {
|
||||||
if (arg.id === this._id) {
|
if (arg.id === this._id) {
|
||||||
// don't raise error event if handler doesn't exist, node
|
// don't raise error event if handler doesn't exist, node
|
||||||
@ -95,7 +111,7 @@ class Notify {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* close notification
|
* Closes notification
|
||||||
*/
|
*/
|
||||||
close() {
|
close() {
|
||||||
if (typeof this._closeNotification === 'function') {
|
if (typeof this._closeNotification === 'function') {
|
||||||
@ -105,7 +121,7 @@ class Notify {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* always allow showing notifications.
|
* Always allow showing notifications.
|
||||||
* @return {string} 'granted'
|
* @return {string} 'granted'
|
||||||
*/
|
*/
|
||||||
static get permission() {
|
static get permission() {
|
||||||
@ -113,14 +129,14 @@ class Notify {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns data object passed in via constructor options
|
* Returns data object passed in via constructor options
|
||||||
*/
|
*/
|
||||||
get data() {
|
get data() {
|
||||||
return this._data;
|
return this._data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add event listeners for 'click', 'close', 'show', 'error' events
|
* Adds event listeners for 'click', 'close', 'show', 'error' events
|
||||||
*
|
*
|
||||||
* @param {String} event event to listen for
|
* @param {String} event event to listen for
|
||||||
* @param {func} cb callback invoked when event occurs
|
* @param {func} cb callback invoked when event occurs
|
||||||
@ -132,7 +148,7 @@ class Notify {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* remove event listeners for 'click', 'close', 'show', 'error' events
|
* Removes event listeners for 'click', 'close', 'show', 'error' events
|
||||||
*
|
*
|
||||||
* @param {String} event event to stop listening for.
|
* @param {String} event event to stop listening for.
|
||||||
* @param {func} cb callback associated with original addEventListener
|
* @param {func} cb callback associated with original addEventListener
|
||||||
@ -144,7 +160,7 @@ class Notify {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* removes all event listeners
|
* Removes all event listeners
|
||||||
*/
|
*/
|
||||||
removeAllEvents() {
|
removeAllEvents() {
|
||||||
this.destroy();
|
this.destroy();
|
||||||
@ -168,10 +184,10 @@ class Notify {
|
|||||||
*/
|
*/
|
||||||
function Queue(emitter) {
|
function Queue(emitter) {
|
||||||
/**
|
/**
|
||||||
* Cache emitter on.
|
* Cache emitter on.
|
||||||
* @api private
|
* @api private
|
||||||
*/
|
*/
|
||||||
var cache = emitter.on;
|
const cache = emitter.on;
|
||||||
let modifiedEmitter = emitter;
|
let modifiedEmitter = emitter;
|
||||||
/**
|
/**
|
||||||
* Emit event and store it if no
|
* Emit event and store it if no
|
||||||
@ -180,7 +196,7 @@ function Queue(emitter) {
|
|||||||
*
|
*
|
||||||
* .queue('message', 'hi');
|
* .queue('message', 'hi');
|
||||||
*
|
*
|
||||||
* @param {String} event
|
* @param {String} topic
|
||||||
*/
|
*/
|
||||||
modifiedEmitter.queue = function(topic) {
|
modifiedEmitter.queue = function(topic) {
|
||||||
this._queue = this._queue || {};
|
this._queue = this._queue || {};
|
||||||
@ -191,18 +207,18 @@ function Queue(emitter) {
|
|||||||
(this._queue[topic] = this._queue[topic] || [])
|
(this._queue[topic] = this._queue[topic] || [])
|
||||||
.push([].slice.call(arguments, 1));
|
.push([].slice.call(arguments, 1));
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listen on the given `event` with `fn`.
|
* Listen on the given `event` with `fn`.
|
||||||
*
|
*
|
||||||
* @param {String} event
|
* @param {String} event
|
||||||
* @param {Function} fn
|
* @param {Function} fn
|
||||||
* @return {Emitter}
|
* @return {Event}
|
||||||
*/
|
*/
|
||||||
modifiedEmitter.on = modifiedEmitter.addEventListener = function(topic, fn) {
|
modifiedEmitter.on = modifiedEmitter.addEventListener = function(topic, fn) {
|
||||||
this._queue = this._queue || {};
|
this._queue = this._queue || {};
|
||||||
var topics = this._queue[topic];
|
const topics = this._queue[topic];
|
||||||
cache.apply(this, arguments);
|
cache.apply(this, arguments);
|
||||||
|
|
||||||
if (!this._callbacks) {
|
if (!this._callbacks) {
|
||||||
@ -211,7 +227,9 @@ function Queue(emitter) {
|
|||||||
this._callbacks[topic] = true;
|
this._callbacks[topic] = true;
|
||||||
|
|
||||||
if (topics) {
|
if (topics) {
|
||||||
for(var i = 0, l = topics.length; i < l; i++) {
|
let i = 0;
|
||||||
|
const l = topics.length;
|
||||||
|
for(; i < l; i++) {
|
||||||
fn.apply(this, topics[i]);
|
fn.apply(this, topics[i]);
|
||||||
}
|
}
|
||||||
delete this._queue[topic];
|
delete this._queue[topic];
|
||||||
|
@ -9,7 +9,9 @@ let selectedDisplay;
|
|||||||
|
|
||||||
renderSettings();
|
renderSettings();
|
||||||
|
|
||||||
// Method that renders the data from user config
|
/**
|
||||||
|
* Method that renders the data from user config
|
||||||
|
*/
|
||||||
function renderSettings() {
|
function renderSettings() {
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
@ -33,6 +35,9 @@ function renderSettings() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the configuration and closes the alert
|
||||||
|
*/
|
||||||
function updateAndClose() {
|
function updateAndClose() {
|
||||||
ipc.send('update-config', {position: selectedPosition, display: selectedDisplay});
|
ipc.send('update-config', {position: selectedPosition, display: selectedDisplay});
|
||||||
ipc.send('close-alert');
|
ipc.send('close-alert');
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
<label class="label">Monitor</label>
|
<label class="label">Monitor</label>
|
||||||
<div id="screens" class="main">
|
<div id="screens" class="main">
|
||||||
<label>Notification shown on Monitor: </label>
|
<label>Notification shown on Monitor: </label>
|
||||||
<select class="selector" id="screen-selector">
|
<select class="selector" id="screen-selector" title="position">
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<label class="label">Position</label>
|
<label class="label">Position</label>
|
||||||
|
@ -41,15 +41,28 @@ app.on('ready', () => {
|
|||||||
electron.screen.on('display-removed', updateScreens);
|
electron.screen.on('display-removed', updateScreens);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update all the screens
|
||||||
|
*/
|
||||||
function updateScreens() {
|
function updateScreens() {
|
||||||
screens = electron.screen.getAllDisplays();
|
screens = electron.screen.getAllDisplays();
|
||||||
|
|
||||||
// Notifying renderer when a display is added/removed
|
// Notifying renderer when a display is added/removed
|
||||||
if (configurationWindow && screens && screens.length >= 0) {
|
if (configurationWindow) {
|
||||||
configurationWindow.webContents.send('screens', screens);
|
// Event that updates the DOM elements
|
||||||
|
// notification position checkbox and monitor selection drop-down
|
||||||
|
configurationWindow.webContents.send('notificationSettings', {position: position, display: display});
|
||||||
|
|
||||||
|
if (screens && screens.length >= 0) {
|
||||||
|
configurationWindow.webContents.send('screens', screens);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the template path
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
function getTemplatePath() {
|
function getTemplatePath() {
|
||||||
let templatePath = path.join(__dirname, 'configure-notification-position.html');
|
let templatePath = path.join(__dirname, 'configure-notification-position.html');
|
||||||
try {
|
try {
|
||||||
@ -60,14 +73,35 @@ function getTemplatePath() {
|
|||||||
return 'file://' + templatePath;
|
return 'file://' + templatePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the configuration window for a specific window
|
||||||
|
* @param windowName
|
||||||
|
*/
|
||||||
function openConfigurationWindow(windowName) {
|
function openConfigurationWindow(windowName) {
|
||||||
let allWindows = BrowserWindow.getAllWindows();
|
const allWindows = BrowserWindow.getAllWindows();
|
||||||
allWindows = allWindows.find((window) => { return window.winName === windowName });
|
const selectedParentWindow = allWindows.find((window) => { return window.winName === windowName });
|
||||||
|
|
||||||
// if we couldn't find any window matching the window name
|
// if we couldn't find any window matching the window name
|
||||||
// it will render as a new window
|
// it will render as a new window
|
||||||
if (allWindows) {
|
if (selectedParentWindow) {
|
||||||
windowConfig.parent = allWindows;
|
windowConfig.parent = selectedParentWindow;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a temporary work around until there
|
||||||
|
* is a fix for the modal window in windows from the electron
|
||||||
|
* issue - https://github.com/electron/electron/issues/10721
|
||||||
|
*/
|
||||||
|
const { x, y, width, height } = selectedParentWindow.getBounds();
|
||||||
|
|
||||||
|
const windowWidth = Math.round(width * 0.5);
|
||||||
|
const windowHeight = Math.round(height * 0.5);
|
||||||
|
|
||||||
|
// Calculating the center of the parent window
|
||||||
|
// to place the configuration window
|
||||||
|
const centerX = x + width / 2.0;
|
||||||
|
const centerY = y + height / 2.0;
|
||||||
|
windowConfig.x = Math.round(centerX - (windowWidth / 2.0));
|
||||||
|
windowConfig.y = Math.round(centerY - (windowHeight / 2.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
configurationWindow = new BrowserWindow(windowConfig);
|
configurationWindow = new BrowserWindow(windowConfig);
|
||||||
@ -94,6 +128,9 @@ function openConfigurationWindow(windowName) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys a window
|
||||||
|
*/
|
||||||
function destroyWindow() {
|
function destroyWindow() {
|
||||||
configurationWindow = null;
|
configurationWindow = null;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
// also to bring pieces of node.js:
|
// also to bring pieces of node.js:
|
||||||
// https://github.com/electron/electron/issues/2984
|
// https://github.com/electron/electron/issues/2984
|
||||||
//
|
//
|
||||||
const { ipcRenderer, remote } = require('electron');
|
const { ipcRenderer, remote, crashReporter } = require('electron');
|
||||||
|
|
||||||
const throttle = require('../utils/throttle.js');
|
const throttle = require('../utils/throttle.js');
|
||||||
const apiEnums = require('../enums/api.js');
|
const apiEnums = require('../enums/api.js');
|
||||||
@ -19,16 +19,23 @@ const apiCmds = apiEnums.cmds;
|
|||||||
const apiName = apiEnums.apiName;
|
const apiName = apiEnums.apiName;
|
||||||
const getMediaSources = require('../desktopCapturer/getSources');
|
const getMediaSources = require('../desktopCapturer/getSources');
|
||||||
|
|
||||||
require('../downloadManager/downloadManager');
|
require('../downloadManager');
|
||||||
|
|
||||||
// bug in electron preventing us from using spellchecker in pop outs
|
// bug in electron preventing us from using spellchecker in pop outs
|
||||||
// https://github.com/electron/electron/issues/4025
|
// https://github.com/electron/electron/issues/4025
|
||||||
// so loading the spellchecker in try catch so that we don't
|
// so loading the spellchecker in try catch so that we don't
|
||||||
// block other method from loading
|
// block other method from loading
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
loadSpellChecker();
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads up the spell checker module
|
||||||
|
*/
|
||||||
|
function loadSpellChecker() {
|
||||||
try {
|
try {
|
||||||
/* eslint-disable global-require */
|
/* eslint-disable global-require */
|
||||||
const SpellCheckerHelper = require('../spellChecker/spellChecker').SpellCheckHelper;
|
const SpellCheckerHelper = require('../spellChecker').SpellCheckHelper;
|
||||||
/* eslint-enable global-require */
|
/* eslint-enable global-require */
|
||||||
// Method to initialize spell checker
|
// Method to initialize spell checker
|
||||||
const spellChecker = new SpellCheckerHelper();
|
const spellChecker = new SpellCheckerHelper();
|
||||||
@ -38,9 +45,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
console.error('unable to load the spell checker module, hence, skipping the spell check feature ' + err);
|
console.error('unable to load the spell checker module, hence, skipping the spell check feature ' + err);
|
||||||
/* eslint-enable no-console */
|
/* eslint-enable no-console */
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
const nodeURL = require('url');
|
|
||||||
|
|
||||||
// hold ref so doesn't get GC'ed
|
// hold ref so doesn't get GC'ed
|
||||||
const local = {
|
const local = {
|
||||||
@ -66,25 +71,6 @@ function createAPI() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// bug in electron is preventing using event 'will-navigate' from working
|
|
||||||
// in sandboxed environment. https://github.com/electron/electron/issues/8841
|
|
||||||
// so in the mean time using this code below to block clicking on A tags.
|
|
||||||
// A tags are allowed if they include href='_blank', this cause 'new-window'
|
|
||||||
// event to be received which is handled properly in windowMgr.js
|
|
||||||
window.addEventListener('beforeunload', function(event) {
|
|
||||||
var newUrl = document.activeElement && document.activeElement.href;
|
|
||||||
if (newUrl) {
|
|
||||||
var currHostName = window.location.hostname;
|
|
||||||
var parsedNewUrl = nodeURL.parse(newUrl);
|
|
||||||
var parsedNewUrlHostName = parsedNewUrl && parsedNewUrl.hostname;
|
|
||||||
if (currHostName !== parsedNewUrlHostName) {
|
|
||||||
/* eslint-disable no-param-reassign */
|
|
||||||
event.returnValue = 'false';
|
|
||||||
/* eslint-enable no-param-reassign */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// note: window.open from main window (if in the same domain) will get
|
// note: window.open from main window (if in the same domain) will get
|
||||||
// api access. window.open in another domain will be opened in the default
|
// api access. window.open in another domain will be opened in the default
|
||||||
// browser (see: handler for event 'new-window' in windowMgr.js)
|
// browser (see: handler for event 'new-window' in windowMgr.js)
|
||||||
@ -95,14 +81,14 @@ function createAPI() {
|
|||||||
window.ssf = {
|
window.ssf = {
|
||||||
getVersionInfo: function() {
|
getVersionInfo: function() {
|
||||||
return new Promise(function(resolve) {
|
return new Promise(function(resolve) {
|
||||||
var appName = remote.app.getName();
|
let appName = remote.app.getName();
|
||||||
var appVer = remote.app.getVersion();
|
let appVer = remote.app.getVersion();
|
||||||
|
|
||||||
const verInfo = {
|
const verInfo = {
|
||||||
containerIdentifier: appName,
|
containerIdentifier: appName,
|
||||||
containerVer: appVer,
|
containerVer: appVer,
|
||||||
apiVer: '1.0.0'
|
apiVer: '1.0.0'
|
||||||
}
|
};
|
||||||
resolve(verInfo);
|
resolve(verInfo);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -126,9 +112,22 @@ function createAPI() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* provides api to allow user to capture portion of screen, see api
|
* provides api to allow user to capture portion of screen, see api
|
||||||
* details in screenSnipper/ScreenSnippet.js
|
* details in screenSnipper/index.js
|
||||||
*/
|
*/
|
||||||
ScreenSnippet: remote.require('./screenSnippet/ScreenSnippet.js').ScreenSnippet,
|
ScreenSnippet: remote.require('./screenSnippet/index.js').ScreenSnippet,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides API to crash the renderer process that calls this function
|
||||||
|
* Is only used for demos.
|
||||||
|
*/
|
||||||
|
crashRendererProcess: function () {
|
||||||
|
// For practical purposes, we don't allow
|
||||||
|
// this method to work in non-dev environments
|
||||||
|
if (!process.env.ELECTRON_DEV) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
process.crash();
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides api for client side searching
|
* Provides api for client side searching
|
||||||
@ -198,7 +197,7 @@ function createAPI() {
|
|||||||
* this registration func is invoked then the protocolHandler callback
|
* this registration func is invoked then the protocolHandler callback
|
||||||
* will be immediately called.
|
* will be immediately called.
|
||||||
*/
|
*/
|
||||||
registerProtocolHandler: function (protocolHandler) {
|
registerProtocolHandler: function(protocolHandler) {
|
||||||
if (typeof protocolHandler === 'function') {
|
if (typeof protocolHandler === 'function') {
|
||||||
|
|
||||||
local.processProtocolAction = protocolHandler;
|
local.processProtocolAction = protocolHandler;
|
||||||
@ -343,6 +342,12 @@ function createAPI() {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
local.ipcRenderer.on('register-crash-reporter', (event, arg) => {
|
||||||
|
if (arg) {
|
||||||
|
crashReporter.start({companyName: arg.companyName, submitURL: arg.submitURL, uploadToServer: arg.uploadToServer, extra: {'process': arg.process, podUrl: arg.podUrl}});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
function updateOnlineStatus() {
|
function updateOnlineStatus() {
|
||||||
local.ipcRenderer.send(apiName, {
|
local.ipcRenderer.send(apiName, {
|
||||||
cmd: apiCmds.isOnline,
|
cmd: apiCmds.isOnline,
|
||||||
@ -354,4 +359,4 @@ function createAPI() {
|
|||||||
window.addEventListener('online', updateOnlineStatus, false);
|
window.addEventListener('online', updateOnlineStatus, false);
|
||||||
|
|
||||||
updateOnlineStatus();
|
updateOnlineStatus();
|
||||||
}
|
}
|
@ -43,6 +43,10 @@ function setProtocolUrl(uri) {
|
|||||||
protocolUrl = uri;
|
protocolUrl = uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gets the protocol url set against an instance
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
function getProtocolUrl() {
|
function getProtocolUrl() {
|
||||||
return protocolUrl;
|
return protocolUrl;
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,12 @@ const path = require('path');
|
|||||||
const { isMac, isDevEnv } = require('../utils/misc.js');
|
const { isMac, isDevEnv } = require('../utils/misc.js');
|
||||||
const log = require('../log.js');
|
const log = require('../log.js');
|
||||||
const logLevels = require('../enums/logLevels.js');
|
const logLevels = require('../enums/logLevels.js');
|
||||||
|
const eventEmitter = require('.././eventEmitter');
|
||||||
|
|
||||||
// static ref to child process, only allow one screen snippet at time, so
|
// static ref to child process, only allow one screen snippet at time, so
|
||||||
// hold ref to prev, so can kill before starting next snippet.
|
// hold ref to prev, so can kill before starting next snippet.
|
||||||
let child;
|
let child;
|
||||||
|
let isAlwaysOnTop;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Captures a user selected portion of the monitor and returns jpeg image
|
* Captures a user selected portion of the monitor and returns jpeg image
|
||||||
@ -47,21 +49,32 @@ class ScreenSnippet {
|
|||||||
// utilize Mac OSX built-in screencapture tool which has been
|
// utilize Mac OSX built-in screencapture tool which has been
|
||||||
// available since OSX ver 10.2.
|
// available since OSX ver 10.2.
|
||||||
captureUtil = '/usr/sbin/screencapture';
|
captureUtil = '/usr/sbin/screencapture';
|
||||||
captureUtilArgs = [ '-i', '-s', '-t', 'jpg', outputFileName ];
|
captureUtilArgs = ['-i', '-s', '-t', 'jpg', outputFileName];
|
||||||
} else {
|
} else {
|
||||||
// use custom built windows screen capture tool
|
// use custom built windows screen capture tool
|
||||||
if (isDevEnv) {
|
if (isDevEnv) {
|
||||||
// for dev env pick up tool from node nodules
|
// for dev env pick up tool from node nodules
|
||||||
captureUtil =
|
captureUtil =
|
||||||
path.join(__dirname,
|
path.join(__dirname,
|
||||||
'../../node_modules/screen-snippet/bin/Release/ScreenSnippet.exe');
|
'../../node_modules/screen-snippet/bin/Release/ScreenSnippet.exe');
|
||||||
} else {
|
} else {
|
||||||
// for production gets installed next to exec.
|
// for production gets installed next to exec.
|
||||||
let execPath = path.dirname(app.getPath('exe'));
|
let execPath = path.dirname(app.getPath('exe'));
|
||||||
captureUtil = path.join(execPath, 'ScreenSnippet.exe');
|
captureUtil = path.join(execPath, 'ScreenSnippet.exe');
|
||||||
}
|
}
|
||||||
|
|
||||||
captureUtilArgs = [ outputFileName ];
|
// Method to verify and disable always on top property
|
||||||
|
// as an issue with the ScreenSnippet.exe not being on top
|
||||||
|
// of the electron wrapper
|
||||||
|
const windows = electron.BrowserWindow.getAllWindows();
|
||||||
|
if (windows && windows.length > 0) {
|
||||||
|
isAlwaysOnTop = windows[ 0 ].isAlwaysOnTop();
|
||||||
|
if (isAlwaysOnTop) {
|
||||||
|
eventEmitter.emit('isAlwaysOnTop', false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
captureUtilArgs = [outputFileName];
|
||||||
}
|
}
|
||||||
|
|
||||||
log.send(logLevels.INFO, 'ScreenSnippet: starting screen capture util: ' + captureUtil + ' with args=' + captureUtilArgs);
|
log.send(logLevels.INFO, 'ScreenSnippet: starting screen capture util: ' + captureUtil + ' with args=' + captureUtilArgs);
|
||||||
@ -72,6 +85,10 @@ class ScreenSnippet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
child = childProcess.execFile(captureUtil, captureUtilArgs, (error) => {
|
child = childProcess.execFile(captureUtil, captureUtilArgs, (error) => {
|
||||||
|
// Method to reset always on top feature
|
||||||
|
if (isAlwaysOnTop) {
|
||||||
|
eventEmitter.emit('isAlwaysOnTop', true);
|
||||||
|
}
|
||||||
// will be called when child process exits.
|
// will be called when child process exits.
|
||||||
if (error && error.killed) {
|
if (error && error.killed) {
|
||||||
// processs was killed, just resolve with no data.
|
// processs was killed, just resolve with no data.
|
||||||
@ -84,9 +101,15 @@ class ScreenSnippet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// this function was moved outside of class since class is exposed to web
|
/**
|
||||||
// client via preload API, we do NOT want web client to be able to call this
|
* this function was moved outside of class since class is exposed to web
|
||||||
// method - then they could read any file on the disk!
|
* client via preload API, we do NOT want web client to be able to call this
|
||||||
|
* method - then they could read any file on the disk!
|
||||||
|
* @param outputFileName
|
||||||
|
* @param resolve
|
||||||
|
* @param reject
|
||||||
|
* @param childProcessErr
|
||||||
|
*/
|
||||||
function readResult(outputFileName, resolve, reject, childProcessErr) {
|
function readResult(outputFileName, resolve, reject, childProcessErr) {
|
||||||
fs.readFile(outputFileName, (readErr, data) => {
|
fs.readFile(outputFileName, (readErr, data) => {
|
||||||
if (readErr) {
|
if (readErr) {
|
||||||
@ -120,8 +143,7 @@ function readResult(outputFileName, resolve, reject, childProcessErr) {
|
|||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
reject(createError(error));
|
reject(createError(error));
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
// remove tmp file (async)
|
// remove tmp file (async)
|
||||||
fs.unlink(outputFileName, function(removeErr) {
|
fs.unlink(outputFileName, function(removeErr) {
|
||||||
// note: node complains if calling async
|
// note: node complains if calling async
|
||||||
@ -136,14 +158,24 @@ function readResult(outputFileName, resolve, reject, childProcessErr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* eslint-disable class-methods-use-this */
|
/* eslint-disable class-methods-use-this */
|
||||||
|
/**
|
||||||
|
* Create an error object with the ERROR level
|
||||||
|
* @param msg
|
||||||
|
* @returns {Error}
|
||||||
|
*/
|
||||||
function createError(msg) {
|
function createError(msg) {
|
||||||
var err = new Error(msg);
|
let err = new Error(msg);
|
||||||
err.type = 'ERROR';
|
err.type = 'ERROR';
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an error object with the WARN level
|
||||||
|
* @param msg
|
||||||
|
* @returns {Error}
|
||||||
|
*/
|
||||||
function createWarn(msg) {
|
function createWarn(msg) {
|
||||||
var err = new Error(msg);
|
let err = new Error(msg);
|
||||||
err.type = 'WARN';
|
err.type = 'WARN';
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -153,4 +185,4 @@ module.exports = {
|
|||||||
ScreenSnippet: ScreenSnippet,
|
ScreenSnippet: ScreenSnippet,
|
||||||
// note: readResult only exposed for testing purposes
|
// note: readResult only exposed for testing purposes
|
||||||
readResult: readResult
|
readResult: readResult
|
||||||
}
|
};
|
@ -5,6 +5,9 @@ const { SpellCheckHandler, ContextMenuListener, ContextMenuBuilder } = require('
|
|||||||
|
|
||||||
class SpellCheckHelper {
|
class SpellCheckHelper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A constructor to create an instance of the spell checker
|
||||||
|
*/
|
||||||
constructor() {
|
constructor() {
|
||||||
this.spellCheckHandler = new SpellCheckHandler();
|
this.spellCheckHandler = new SpellCheckHandler();
|
||||||
}
|
}
|
@ -7,7 +7,7 @@ const logLevels = require('../enums/logLevels.js');
|
|||||||
* Search given argv for argName using exact match or starts with.
|
* Search given argv for argName using exact match or starts with.
|
||||||
* @param {Array} argv Array of strings
|
* @param {Array} argv Array of strings
|
||||||
* @param {String} argName Arg name to search for.
|
* @param {String} argName Arg name to search for.
|
||||||
* @param {bool} exactMatch If true then look for exact match otherwise
|
* @param {Boolean} exactMatch If true then look for exact match otherwise
|
||||||
* try finding arg that starts with argName.
|
* try finding arg that starts with argName.
|
||||||
* @return {String} If found, returns the arg, otherwise null.
|
* @return {String} If found, returns the arg, otherwise null.
|
||||||
*/
|
*/
|
||||||
@ -26,4 +26,5 @@ function getCmdLineArg(argv, argName, exactMatch) {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
module.exports = getCmdLineArg
|
|
||||||
|
module.exports = getCmdLineArg;
|
||||||
|
@ -7,12 +7,11 @@
|
|||||||
* @return {String} guid value in string
|
* @return {String} guid value in string
|
||||||
*/
|
*/
|
||||||
function getGuid() {
|
function getGuid() {
|
||||||
const guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,
|
||||||
function(c) {
|
function (c) {
|
||||||
var r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
|
let r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
|
||||||
return v.toString(16);
|
return v.toString(16);
|
||||||
});
|
});
|
||||||
return guid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = getGuid;
|
module.exports = getGuid;
|
||||||
|
@ -5,17 +5,17 @@ const { isMac } = require('./misc.js');
|
|||||||
const log = require('../log.js');
|
const log = require('../log.js');
|
||||||
const logLevels = require('../enums/logLevels.js');
|
const logLevels = require('../enums/logLevels.js');
|
||||||
|
|
||||||
var Registry = require('winreg');
|
let Registry = require('winreg');
|
||||||
var symphonyRegistryHKCU = new Registry({
|
let symphonyRegistryHKCU = new Registry({
|
||||||
hive: Registry.HKCU,
|
hive: Registry.HKCU,
|
||||||
key: symphonyRegistry
|
key: symphonyRegistry
|
||||||
});
|
});
|
||||||
|
|
||||||
var symphonyRegistryHKLM = new Registry({
|
let symphonyRegistryHKLM = new Registry({
|
||||||
key: symphonyRegistry
|
key: symphonyRegistry
|
||||||
});
|
});
|
||||||
|
|
||||||
var symphonyRegistryHKLM6432 = new Registry({
|
let symphonyRegistryHKLM6432 = new Registry({
|
||||||
key: symphonyRegistry.replace('\\Software','\\Software\\WOW6432Node')
|
key: symphonyRegistry.replace('\\Software','\\Software\\WOW6432Node')
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -24,24 +24,24 @@ var symphonyRegistryHKLM6432 = new Registry({
|
|||||||
* that are intended to be used as global (or default) value for all users
|
* that are intended to be used as global (or default) value for all users
|
||||||
* running this app.
|
* running this app.
|
||||||
*/
|
*/
|
||||||
var getRegistry = function (name) {
|
let getRegistry = function (name) {
|
||||||
var promise = new Promise(function(resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
if (isMac) {
|
if (isMac) {
|
||||||
reject('registry is not supported for mac osx.');
|
reject('registry is not supported for mac osx.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Try to get registry on HKEY_CURRENT_USER
|
//Try to get registry on HKEY_CURRENT_USER
|
||||||
symphonyRegistryHKCU.get( name, function( err1, reg1 ) {
|
symphonyRegistryHKCU.get(name, function (err1, reg1) {
|
||||||
if (!err1 && reg1 !==null && reg1.value) {
|
if (!err1 && reg1 !== null && reg1.value) {
|
||||||
log.send(logLevels.WARN, 'getRegistry: Cannot find ' + name + ' Registry. Using HKCU');
|
log.send(logLevels.WARN, 'getRegistry: Cannot find ' + name + ' Registry. Using HKCU');
|
||||||
resolve(reg1.value);
|
resolve(reg1.value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Try to get registry on HKEY_LOCAL_MACHINE
|
//Try to get registry on HKEY_LOCAL_MACHINE
|
||||||
symphonyRegistryHKLM.get( name, function( err2, reg2 ) {
|
symphonyRegistryHKLM.get(name, function (err2, reg2) {
|
||||||
if ( !err2 && reg2!==null && reg2.value) {
|
if (!err2 && reg2 !== null && reg2.value) {
|
||||||
log.send(logLevels.WARN, 'getRegistry: Cannot find ' + name + ' Registry. Using HKLM');
|
log.send(logLevels.WARN, 'getRegistry: Cannot find ' + name + ' Registry. Using HKLM');
|
||||||
resolve(reg2.value);
|
resolve(reg2.value);
|
||||||
return;
|
return;
|
||||||
@ -49,18 +49,16 @@ var getRegistry = function (name) {
|
|||||||
|
|
||||||
// Try to get registry on HKEY_LOCAL_MACHINE in case 32bit app installed on 64bit system.
|
// Try to get registry on HKEY_LOCAL_MACHINE in case 32bit app installed on 64bit system.
|
||||||
// winreg does not merge keys as normally windows does.
|
// winreg does not merge keys as normally windows does.
|
||||||
symphonyRegistryHKLM6432.get( name, function( err3, reg3 ) {
|
symphonyRegistryHKLM6432.get(name, function (err3, reg3) {
|
||||||
if ( !err3 && reg3!==null && reg3.value) {
|
if (!err3 && reg3 !== null && reg3.value) {
|
||||||
resolve(reg3.value);
|
resolve(reg3.value);
|
||||||
} else{
|
} else {
|
||||||
reject('Cannot find PodUrl Registry. Using default url.');
|
reject('Cannot find PodUrl Registry. Using default url.');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return promise;
|
module.exports = getRegistry;
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = getRegistry
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
'use strict'
|
'use strict';
|
||||||
|
|
||||||
const electron = require('electron');
|
const electron = require('electron');
|
||||||
|
|
||||||
@ -6,8 +6,8 @@ const electron = require('electron');
|
|||||||
/**
|
/**
|
||||||
* Returns true if given rectangle is contained within the workArea of at
|
* Returns true if given rectangle is contained within the workArea of at
|
||||||
* least one of the screens.
|
* least one of the screens.
|
||||||
* @param {x: Number, y: Number, width: Number, height: Number} rect
|
* @param {Object} rect - ex:- {x: Number, y: Number, width: Number, height: Number}
|
||||||
* @return {Boolean} true if condition in desc is met.
|
* @return {Boolean} true if condition in desc is met.
|
||||||
*/
|
*/
|
||||||
function isInDisplayBounds(rect) {
|
function isInDisplayBounds(rect) {
|
||||||
if (!rect) {
|
if (!rect) {
|
||||||
|
207
js/windowMgr.js
207
js/windowMgr.js
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
const electron = require('electron');
|
const electron = require('electron');
|
||||||
const app = electron.app;
|
const app = electron.app;
|
||||||
|
const crashReporter = electron.crashReporter;
|
||||||
const BrowserWindow = electron.BrowserWindow;
|
const BrowserWindow = electron.BrowserWindow;
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const nodeURL = require('url');
|
const nodeURL = require('url');
|
||||||
@ -16,13 +17,13 @@ const log = require('./log.js');
|
|||||||
const logLevels = require('./enums/logLevels.js');
|
const logLevels = require('./enums/logLevels.js');
|
||||||
const notify = require('./notify/electron-notify.js');
|
const notify = require('./notify/electron-notify.js');
|
||||||
const eventEmitter = require('./eventEmitter');
|
const eventEmitter = require('./eventEmitter');
|
||||||
|
|
||||||
const throttle = require('./utils/throttle.js');
|
const throttle = require('./utils/throttle.js');
|
||||||
const { getConfigField, updateConfigField } = require('./config.js');
|
const { getConfigField, updateConfigField } = require('./config.js');
|
||||||
const { isMac, isNodeEnv } = require('./utils/misc');
|
const { isMac, isNodeEnv } = require('./utils/misc');
|
||||||
|
|
||||||
// show dialog when certificate errors occur
|
// show dialog when certificate errors occur
|
||||||
require('./dialogs/showCertError.js');
|
require('./dialogs/showCertError.js');
|
||||||
|
require('./dialogs/showBasicAuth.js');
|
||||||
|
|
||||||
// Keep a global reference of the window object, if you don't, the window will
|
// Keep a global reference of the window object, if you don't, the window will
|
||||||
// be closed automatically when the JavaScript object is garbage collected.
|
// be closed automatically when the JavaScript object is garbage collected.
|
||||||
@ -40,20 +41,42 @@ let sandboxed = false;
|
|||||||
const preloadMainScript = path.join(__dirname, 'preload/_preloadMain.js');
|
const preloadMainScript = path.join(__dirname, 'preload/_preloadMain.js');
|
||||||
|
|
||||||
const MIN_WIDTH = 300;
|
const MIN_WIDTH = 300;
|
||||||
const MIN_HEIGHT = 600;
|
const MIN_HEIGHT = 300;
|
||||||
|
|
||||||
|
// Default window size for pop-out windows
|
||||||
|
const DEFAULT_WIDTH = 300;
|
||||||
|
const DEFAULT_HEIGHT = 600;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a window key
|
||||||
|
* @param key
|
||||||
|
* @param browserWin
|
||||||
|
*/
|
||||||
function addWindowKey(key, browserWin) {
|
function addWindowKey(key, browserWin) {
|
||||||
windows[key] = browserWin;
|
windows[key] = browserWin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a window key
|
||||||
|
* @param key
|
||||||
|
*/
|
||||||
function removeWindowKey(key) {
|
function removeWindowKey(key) {
|
||||||
delete windows[key];
|
delete windows[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the parsed url
|
||||||
|
* @param url
|
||||||
|
* @returns {Url}
|
||||||
|
*/
|
||||||
function getParsedUrl(url) {
|
function getParsedUrl(url) {
|
||||||
return nodeURL.parse(url);
|
return nodeURL.parse(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the main window
|
||||||
|
* @param initialUrl
|
||||||
|
*/
|
||||||
function createMainWindow(initialUrl) {
|
function createMainWindow(initialUrl) {
|
||||||
getConfigField('mainWinPos').then(
|
getConfigField('mainWinPos').then(
|
||||||
function (bounds) {
|
function (bounds) {
|
||||||
@ -63,9 +86,14 @@ function createMainWindow(initialUrl) {
|
|||||||
// failed, use default bounds
|
// failed, use default bounds
|
||||||
doCreateMainWindow(initialUrl, null);
|
doCreateMainWindow(initialUrl, null);
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the main window with bounds
|
||||||
|
* @param initialUrl
|
||||||
|
* @param initialBounds
|
||||||
|
*/
|
||||||
function doCreateMainWindow(initialUrl, initialBounds) {
|
function doCreateMainWindow(initialUrl, initialBounds) {
|
||||||
let url = initialUrl;
|
let url = initialUrl;
|
||||||
let key = getGuid();
|
let key = getGuid();
|
||||||
@ -154,7 +182,27 @@ function doCreateMainWindow(initialUrl, initialBounds) {
|
|||||||
|
|
||||||
mainWindow.webContents.on('did-fail-load', function (event, errorCode,
|
mainWindow.webContents.on('did-fail-load', function (event, errorCode,
|
||||||
errorDesc, validatedURL) {
|
errorDesc, validatedURL) {
|
||||||
loadErrors.showLoadFailure(mainWindow, validatedURL, errorDesc, errorCode, retry);
|
loadErrors.showLoadFailure(mainWindow, validatedURL, errorDesc, errorCode, retry, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// In case a renderer process crashes, provide an
|
||||||
|
// option for the user to either reload or close the window
|
||||||
|
mainWindow.webContents.on('crashed', function () {
|
||||||
|
const options = {
|
||||||
|
type: 'error',
|
||||||
|
title: 'Renderer Process Crashed',
|
||||||
|
message: 'Oops! Looks like we have had a crash. Please reload or close this window.',
|
||||||
|
buttons: ['Reload', 'Close']
|
||||||
|
};
|
||||||
|
|
||||||
|
electron.dialog.showMessageBox(options, function (index) {
|
||||||
|
if (index === 0) {
|
||||||
|
mainWindow.reload();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mainWindow.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
addWindowKey(key, mainWindow);
|
addWindowKey(key, mainWindow);
|
||||||
@ -179,7 +227,7 @@ function doCreateMainWindow(initialUrl, initialBounds) {
|
|||||||
|
|
||||||
function destroyAllWindows() {
|
function destroyAllWindows() {
|
||||||
let keys = Object.keys(windows);
|
let keys = Object.keys(windows);
|
||||||
for (var i = 0, len = keys.length; i < len; i++) {
|
for (let i = 0, len = keys.length; i < len; i++) {
|
||||||
let winKey = keys[i];
|
let winKey = keys[i];
|
||||||
removeWindowKey(winKey);
|
removeWindowKey(winKey);
|
||||||
}
|
}
|
||||||
@ -208,15 +256,22 @@ function doCreateMainWindow(initialUrl, initialBounds) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// bug in electron is preventing this from working in sandboxed evt...
|
getConfigField('url')
|
||||||
// https://github.com/electron/electron/issues/8841
|
.then(initializeCrashReporter)
|
||||||
mainWindow.webContents.on('will-navigate', function(event, willNavUrl) {
|
.catch(app.quit);
|
||||||
if (!sandboxed) {
|
|
||||||
return;
|
function initializeCrashReporter(podUrl) {
|
||||||
}
|
getConfigField('crashReporter')
|
||||||
event.preventDefault();
|
.then((crashReporterConfig) => {
|
||||||
openUrlInDefaultBrower(willNavUrl);
|
log.send(logLevels.INFO, 'Initializing crash reporter on the main window!');
|
||||||
});
|
crashReporter.start({companyName: crashReporterConfig.companyName, submitURL: crashReporterConfig.submitURL, uploadToServer: crashReporterConfig.uploadToServer, extra: {'process': 'renderer / main window', podUrl: podUrl}});
|
||||||
|
log.send(logLevels.INFO, 'initialized crash reporter on the main window!');
|
||||||
|
mainWindow.webContents.send('register-crash-reporter', {companyName: crashReporterConfig.companyName, submitURL: crashReporterConfig.submitURL, uploadToServer: crashReporterConfig.uploadToServer, process: 'preload script / main window renderer'});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
log.send(logLevels.ERROR, 'Unable to initialize crash reporter in the main window. Error is -> ' + err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// open external links in default browser - a tag with href='_blank' or window.open
|
// open external links in default browser - a tag with href='_blank' or window.open
|
||||||
mainWindow.webContents.on('new-window', function (event, newWinUrl,
|
mainWindow.webContents.on('new-window', function (event, newWinUrl,
|
||||||
@ -243,11 +298,11 @@ function doCreateMainWindow(initialUrl, initialBounds) {
|
|||||||
let x = 0;
|
let x = 0;
|
||||||
let y = 0;
|
let y = 0;
|
||||||
|
|
||||||
let width = newWinOptions.width || MIN_WIDTH;
|
let width = newWinOptions.width || DEFAULT_WIDTH;
|
||||||
let height = newWinOptions.height || MIN_HEIGHT;
|
let height = newWinOptions.height || DEFAULT_HEIGHT;
|
||||||
|
|
||||||
// try getting x and y position from query parameters
|
// try getting x and y position from query parameters
|
||||||
var query = newWinParsedUrl && querystring.parse(newWinParsedUrl.query);
|
let query = newWinParsedUrl && querystring.parse(newWinParsedUrl.query);
|
||||||
if (query && query.x && query.y) {
|
if (query && query.x && query.y) {
|
||||||
let newX = Number.parseInt(query.x, 10);
|
let newX = Number.parseInt(query.x, 10);
|
||||||
let newY = Number.parseInt(query.y, 10);
|
let newY = Number.parseInt(query.y, 10);
|
||||||
@ -273,8 +328,8 @@ function doCreateMainWindow(initialUrl, initialBounds) {
|
|||||||
/* eslint-disable no-param-reassign */
|
/* eslint-disable no-param-reassign */
|
||||||
newWinOptions.x = x;
|
newWinOptions.x = x;
|
||||||
newWinOptions.y = y;
|
newWinOptions.y = y;
|
||||||
newWinOptions.width = Math.max(width, MIN_WIDTH);
|
newWinOptions.width = Math.max(width, DEFAULT_WIDTH);
|
||||||
newWinOptions.height = Math.max(height, MIN_HEIGHT);
|
newWinOptions.height = Math.max(height, DEFAULT_HEIGHT);
|
||||||
newWinOptions.minWidth = MIN_WIDTH;
|
newWinOptions.minWidth = MIN_WIDTH;
|
||||||
newWinOptions.minHeight = MIN_HEIGHT;
|
newWinOptions.minHeight = MIN_HEIGHT;
|
||||||
newWinOptions.alwaysOnTop = alwaysOnTop;
|
newWinOptions.alwaysOnTop = alwaysOnTop;
|
||||||
@ -292,36 +347,100 @@ function doCreateMainWindow(initialUrl, initialBounds) {
|
|||||||
if (browserWin) {
|
if (browserWin) {
|
||||||
log.send(logLevels.INFO, 'loaded pop-out window url: ' + newWinParsedUrl);
|
log.send(logLevels.INFO, 'loaded pop-out window url: ' + newWinParsedUrl);
|
||||||
|
|
||||||
|
getConfigField('url')
|
||||||
|
.then((podUrl) => {
|
||||||
|
getConfigField('crashReporter')
|
||||||
|
.then((crashReporterConfig) => {
|
||||||
|
crashReporter.start({companyName: crashReporterConfig.companyName, submitURL: crashReporterConfig.submitURL, uploadToServer: crashReporterConfig.uploadToServer, extra: {'process': 'renderer / child window', podUrl: podUrl}});
|
||||||
|
log.send(logLevels.INFO, 'initialized crash reporter on a child window!');
|
||||||
|
browserWin.webContents.send('register-crash-reporter', {companyName: crashReporterConfig.companyName, submitURL: crashReporterConfig.submitURL, uploadToServer: crashReporterConfig.uploadToServer, process: 'preload script / child window renderer'});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
log.send(logLevels.ERROR, 'Unable to initialize crash reporter in the child window. Error is -> ' + err);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(app.quit);
|
||||||
|
|
||||||
browserWin.winName = frameName;
|
browserWin.winName = frameName;
|
||||||
browserWin.setAlwaysOnTop(alwaysOnTop);
|
browserWin.setAlwaysOnTop(alwaysOnTop);
|
||||||
|
|
||||||
browserWin.once('closed', function () {
|
let handleChildWindowClosed = () => {
|
||||||
removeWindowKey(newWinKey);
|
removeWindowKey(newWinKey);
|
||||||
browserWin.removeListener('move', throttledBoundsChange);
|
browserWin.removeListener('move', throttledBoundsChange);
|
||||||
browserWin.removeListener('resize', throttledBoundsChange);
|
browserWin.removeListener('resize', throttledBoundsChange);
|
||||||
|
};
|
||||||
|
|
||||||
|
browserWin.once('closed', () => {
|
||||||
|
handleChildWindowClosed();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
browserWin.on('close', () => {
|
||||||
|
browserWin.webContents.removeListener('new-window', handleChildNewWindowEvent);
|
||||||
|
browserWin.webContents.removeListener('crashed', handleChildWindowCrashEvent);
|
||||||
|
});
|
||||||
|
|
||||||
|
let handleChildWindowCrashEvent = () => {
|
||||||
|
const options = {
|
||||||
|
type: 'error',
|
||||||
|
title: 'Renderer Process Crashed',
|
||||||
|
message: 'Oops! Looks like we have had a crash. Please reload or close this window.',
|
||||||
|
buttons: ['Reload', 'Close']
|
||||||
|
};
|
||||||
|
|
||||||
|
electron.dialog.showMessageBox(options, function (index) {
|
||||||
|
if (index === 0) {
|
||||||
|
browserWin.reload();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
browserWin.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
browserWin.webContents.on('crashed', handleChildWindowCrashEvent);
|
||||||
|
|
||||||
|
let handleChildNewWindowEvent = (childEvent, childWinUrl) => {
|
||||||
|
childEvent.preventDefault();
|
||||||
|
openUrlInDefaultBrowser(childWinUrl);
|
||||||
|
};
|
||||||
|
|
||||||
|
// In case we navigate to an external link from inside a pop-out,
|
||||||
|
// we open that link in an external browser rather than creating
|
||||||
|
// a new window
|
||||||
|
browserWin.webContents.on('new-window', handleChildNewWindowEvent);
|
||||||
|
|
||||||
addWindowKey(newWinKey, browserWin);
|
addWindowKey(newWinKey, browserWin);
|
||||||
|
|
||||||
|
// Method that sends bound changes as soon
|
||||||
|
// as a new window is created
|
||||||
|
// issue https://perzoinc.atlassian.net/browse/ELECTRON-172
|
||||||
|
sendChildWinBoundsChange(browserWin);
|
||||||
|
|
||||||
// throttle changes so we don't flood client.
|
// throttle changes so we don't flood client.
|
||||||
let throttledBoundsChange = throttle(1000,
|
let throttledBoundsChange = throttle(1000,
|
||||||
sendChildWinBoundsChange.bind(null, browserWin));
|
sendChildWinBoundsChange.bind(null, browserWin));
|
||||||
browserWin.on('move', throttledBoundsChange);
|
browserWin.on('move', throttledBoundsChange);
|
||||||
browserWin.on('resize', throttledBoundsChange);
|
browserWin.on('resize', throttledBoundsChange);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
openUrlInDefaultBrower(newWinUrl)
|
openUrlInDefaultBrowser(newWinUrl);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the event before-quit emitted by electron
|
||||||
|
*/
|
||||||
app.on('before-quit', function () {
|
app.on('before-quit', function () {
|
||||||
willQuitApp = true;
|
willQuitApp = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the main window bounds
|
||||||
|
*/
|
||||||
function saveMainWinBounds() {
|
function saveMainWinBounds() {
|
||||||
let newBounds = getWindowSizeAndPosition(mainWindow);
|
let newBounds = getWindowSizeAndPosition(mainWindow);
|
||||||
|
|
||||||
@ -330,10 +449,19 @@ function saveMainWinBounds() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the main window
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
function getMainWindow() {
|
function getMainWindow() {
|
||||||
return mainWindow;
|
return mainWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a window's size and position
|
||||||
|
* @param window
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
function getWindowSizeAndPosition(window) {
|
function getWindowSizeAndPosition(window) {
|
||||||
if (window) {
|
if (window) {
|
||||||
let newPos = window.getPosition();
|
let newPos = window.getPosition();
|
||||||
@ -353,14 +481,28 @@ function getWindowSizeAndPosition(window) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the main window
|
||||||
|
*/
|
||||||
function showMainWindow() {
|
function showMainWindow() {
|
||||||
mainWindow.show();
|
mainWindow.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells if a window is the main window
|
||||||
|
* @param win
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
function isMainWindow(win) {
|
function isMainWindow(win) {
|
||||||
return mainWindow === win;
|
return mainWindow === win;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the window and a key has a window
|
||||||
|
* @param win
|
||||||
|
* @param winKey
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
function hasWindow(win, winKey) {
|
function hasWindow(win, winKey) {
|
||||||
if (win instanceof BrowserWindow) {
|
if (win instanceof BrowserWindow) {
|
||||||
let browserWin = windows[winKey];
|
let browserWin = windows[winKey];
|
||||||
@ -370,12 +512,16 @@ function hasWindow(win, winKey) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets if a user is online
|
||||||
|
* @param status
|
||||||
|
*/
|
||||||
function setIsOnline(status) {
|
function setIsOnline(status) {
|
||||||
isOnline = status;
|
isOnline = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries finding a window we have created with given name. If founds then
|
* Tries finding a window we have created with given name. If found, then
|
||||||
* brings to front and gives focus.
|
* brings to front and gives focus.
|
||||||
* @param {String} windowName Name of target window. Note: main window has
|
* @param {String} windowName Name of target window. Note: main window has
|
||||||
* name 'main'.
|
* name 'main'.
|
||||||
@ -417,8 +563,12 @@ function sendChildWinBoundsChange(window) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function openUrlInDefaultBrower(urlToOpen) {
|
/**
|
||||||
if (urlToOpen) {
|
* Opens an external url in the system's default browser
|
||||||
|
* @param urlToOpen
|
||||||
|
*/
|
||||||
|
function openUrlInDefaultBrowser(urlToOpen) {
|
||||||
|
if (urlToOpen) {
|
||||||
electron.shell.openExternal(urlToOpen);
|
electron.shell.openExternal(urlToOpen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -514,11 +664,8 @@ function checkExternalDisplay(appBounds) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rightMost > bounds.x + bounds.width || bottomMost > bounds.y + bounds.height) {
|
return !(rightMost > bounds.x + bounds.width || bottomMost > bounds.y + bounds.height);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
15
package.json
15
package.json
@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "Symphony",
|
"name": "Symphony",
|
||||||
"productName": "Symphony",
|
"productName": "Symphony",
|
||||||
"version": "1.0.1",
|
"version": "2.0.0",
|
||||||
|
"buildNumber": "",
|
||||||
"description": "Symphony desktop app (Foundation ODP)",
|
"description": "Symphony desktop app (Foundation ODP)",
|
||||||
"author": "Symphony",
|
"author": "Symphony",
|
||||||
"main": "js/main.js",
|
"main": "js/main.js",
|
||||||
@ -28,7 +29,9 @@
|
|||||||
"transformIgnorePatterns": []
|
"transformIgnorePatterns": []
|
||||||
},
|
},
|
||||||
"build": {
|
"build": {
|
||||||
"asarUnpack": ["node_modules/@paulcbetts/cld/build/Release/cld.node"],
|
"asarUnpack": [
|
||||||
|
"node_modules/@paulcbetts/cld/build/Release/cld.node"
|
||||||
|
],
|
||||||
"files": [
|
"files": [
|
||||||
"!coverage/*",
|
"!coverage/*",
|
||||||
"!installer/*",
|
"!installer/*",
|
||||||
@ -81,7 +84,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"browserify": "^14.1.0",
|
"browserify": "^14.1.0",
|
||||||
"cross-env": "^3.2.4",
|
"cross-env": "^3.2.4",
|
||||||
"electron": "1.7.5",
|
"electron": "1.7.8",
|
||||||
"electron-builder": "^13.9.0",
|
"electron-builder": "^13.9.0",
|
||||||
"electron-builder-squirrel-windows": "^12.3.0",
|
"electron-builder-squirrel-windows": "^12.3.0",
|
||||||
"electron-packager": "^8.5.2",
|
"electron-packager": "^8.5.2",
|
||||||
@ -103,11 +106,15 @@
|
|||||||
"async.mapseries": "^0.5.2",
|
"async.mapseries": "^0.5.2",
|
||||||
"auto-launch": "^5.0.1",
|
"auto-launch": "^5.0.1",
|
||||||
"electron-dl": "^1.9.0",
|
"electron-dl": "^1.9.0",
|
||||||
"electron-spellchecker": "^1.2.0",
|
"electron-log": "^2.2.7",
|
||||||
|
"electron-spellchecker": "^1.1.2",
|
||||||
"electron-squirrel-startup": "^1.0.0",
|
"electron-squirrel-startup": "^1.0.0",
|
||||||
"ffi": "^2.2.0",
|
"ffi": "^2.2.0",
|
||||||
"filesize": "^3.5.10",
|
"filesize": "^3.5.10",
|
||||||
"keymirror": "0.1.1",
|
"keymirror": "0.1.1",
|
||||||
|
"lodash.omit": "^4.5.0",
|
||||||
|
"lodash.pick": "^4.4.0",
|
||||||
|
"lodash.difference": "^4.5.0",
|
||||||
"randomstring": "^1.1.5",
|
"randomstring": "^1.1.5",
|
||||||
"ref": "^1.3.4",
|
"ref": "^1.3.4",
|
||||||
"shell-path": "^2.1.0",
|
"shell-path": "^2.1.0",
|
||||||
|
@ -1,27 +1,32 @@
|
|||||||
const downloadManager = require('../js/downloadManager/downloadManager');
|
const downloadManager = require('../js/downloadManager');
|
||||||
const electron = require('./__mocks__/electron');
|
const electron = require('./__mocks__/electron');
|
||||||
|
|
||||||
describe('download manager', function () {
|
describe('download manager', function() {
|
||||||
describe('Download Manager to create DOM once download is initiated', function () {
|
describe('Download Manager to create DOM once download is initiated', function() {
|
||||||
beforeEach(function () {
|
beforeEach(function() {
|
||||||
global.document.body.innerHTML =
|
global.document.body.innerHTML =
|
||||||
'<div id="download-main">' +
|
'<div id="download-main">' +
|
||||||
'</div>';
|
'</div>';
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should inject download bar element into DOM once download is initiated', function () {
|
it('should inject download bar element into DOM once download is initiated', function() {
|
||||||
electron.ipcRenderer.send('downloadCompleted', { _id: '12345', fileName: 'test', total: 100 });
|
electron.ipcRenderer.send('downloadCompleted', { _id: '12345', fileName: 'test.png', total: 100 });
|
||||||
expect(document.getElementsByClassName('text-cutoff')[0].innerHTML).toBe('test');
|
expect(document.getElementsByClassName('text-cutoff')[0].innerHTML).toBe('test.png');
|
||||||
expect(document.getElementById('per').innerHTML).toBe('100 Downloaded');
|
expect(document.getElementById('per').innerHTML).toBe('100 Downloaded');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should inject multiple download items during multiple downloads', function () {
|
it('should inject multiple download items during multiple downloads', function() {
|
||||||
electron.ipcRenderer.send('downloadCompleted', { _id: '12345', fileName: 'test', total: 100 });
|
electron.ipcRenderer.send('downloadCompleted', { _id: '12345', fileName: 'test.png', total: 100 });
|
||||||
electron.ipcRenderer.send('downloadCompleted', { _id: '67890', fileName: 'test1', total: 200 });
|
electron.ipcRenderer.send('downloadCompleted', { _id: '67890', fileName: 'test.png', total: 200 });
|
||||||
|
|
||||||
let fileNames = document.getElementsByClassName('text-cutoff');
|
let fileNames = document.getElementsByClassName('text-cutoff');
|
||||||
expect(fileNames[0].innerHTML).toBe('test1');
|
let fNames = [];
|
||||||
expect(fileNames[1].innerHTML).toBe('test');
|
|
||||||
|
for (var i = 0; i < fileNames.length; i++) {
|
||||||
|
fNames.push(fileNames[i].innerHTML);
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(fNames).toEqual(expect.arrayContaining(['test (1).png', 'test (2).png']));
|
||||||
expect(document.getElementById('per').innerHTML).toBe('100 Downloaded');
|
expect(document.getElementById('per').innerHTML).toBe('100 Downloaded');
|
||||||
|
|
||||||
let downloadElements = document.getElementsByClassName('download-element');
|
let downloadElements = document.getElementsByClassName('download-element');
|
||||||
@ -31,23 +36,23 @@ describe('download manager', function () {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Download Manager to initiate footer', function () {
|
describe('Download Manager to initiate footer', function() {
|
||||||
beforeEach(function () {
|
beforeEach(function() {
|
||||||
global.document.body.innerHTML =
|
global.document.body.innerHTML =
|
||||||
'<div id="footer" class="hidden">' +
|
'<div id="footer" class="hidden">' +
|
||||||
'<div id="download-manager-footer">' +
|
'<div id="download-manager-footer">' +
|
||||||
'<div id="download-main">' +
|
'<div id="download-main">' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should inject dom element once download is completed', function () {
|
it('should inject dom element once download is completed', function() {
|
||||||
electron.ipcRenderer.send('downloadProgress');
|
electron.ipcRenderer.send('downloadProgress');
|
||||||
expect(document.getElementById('footer').classList).not.toContain('hidden');
|
expect(document.getElementById('footer').classList).not.toContain('hidden');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should remove the download bar and clear up the download items', function () {
|
it('should remove the download bar and clear up the download items', function() {
|
||||||
|
|
||||||
electron.ipcRenderer.send('downloadProgress');
|
electron.ipcRenderer.send('downloadProgress');
|
||||||
expect(document.getElementById('footer').classList).not.toContain('hidden');
|
expect(document.getElementById('footer').classList).not.toContain('hidden');
|
||||||
@ -59,19 +64,19 @@ describe('download manager', function () {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Download Manager to initiate footer', function () {
|
describe('Download Manager to initiate footer', function() {
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function() {
|
||||||
global.document.body.innerHTML =
|
global.document.body.innerHTML =
|
||||||
'<div id="footer" class="hidden">' +
|
'<div id="footer" class="hidden">' +
|
||||||
'<div id="download-manager-footer">' +
|
'<div id="download-manager-footer">' +
|
||||||
'<div id="download-main">' +
|
'<div id="download-main">' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should inject ul element if not found', function () {
|
it('should inject ul element if not found', function() {
|
||||||
|
|
||||||
electron.ipcRenderer.send('downloadProgress');
|
electron.ipcRenderer.send('downloadProgress');
|
||||||
|
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
|
const { ScreenSnippet, readResult } = require('../js/screenSnippet');
|
||||||
const { ScreenSnippet, readResult } = require('../js/screenSnippet/ScreenSnippet.js');
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const os = require('os');
|
const os = require('os');
|
||||||
|
|
||||||
const { isMac } = require('../js/utils/misc.js')
|
const { isMac } = require('../js/utils/misc.js');
|
||||||
|
|
||||||
const snippetBase64 = require('./fixtures/snippet/snippet-base64.js');
|
const snippetBase64 = require('./fixtures/snippet/snippet-base64.js');
|
||||||
|
|
||||||
@ -27,7 +26,7 @@ function mockedExecFile(util, args, doneCallback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function copyTestFile(destFile, done) {
|
function copyTestFile(destFile, done) {
|
||||||
const testfile = path.join(__dirname ,
|
const testfile = path.join(__dirname,
|
||||||
'fixtures/snippet/ScreenSnippet.jpeg');
|
'fixtures/snippet/ScreenSnippet.jpeg');
|
||||||
|
|
||||||
let reader = fs.createReadStream(testfile);
|
let reader = fs.createReadStream(testfile);
|
||||||
@ -43,7 +42,7 @@ function copyTestFile(destFile, done) {
|
|||||||
function createTestFile(done) {
|
function createTestFile(done) {
|
||||||
let tmpDir = os.tmpdir();
|
let tmpDir = os.tmpdir();
|
||||||
const testFileName = path.join(tmpDir,
|
const testFileName = path.join(tmpDir,
|
||||||
'ScreenSnippet-' + Date.now() + '.jpeg');
|
'ScreenSnippet-' + Date.now() + '.jpeg');
|
||||||
|
|
||||||
copyTestFile(testFileName, function() {
|
copyTestFile(testFileName, function() {
|
||||||
done(testFileName)
|
done(testFileName)
|
||||||
@ -65,7 +64,7 @@ describe('Tests for ScreenSnippet', function() {
|
|||||||
expect(rsp.type).toEqual('image/jpg;base64');
|
expect(rsp.type).toEqual('image/jpg;base64');
|
||||||
expect(rsp.data).toEqual(snippetBase64);
|
expect(rsp.data).toEqual(snippetBase64);
|
||||||
done();
|
done();
|
||||||
};
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +103,7 @@ describe('Tests for ScreenSnippet', function() {
|
|||||||
// skip test for windows - until feature is supported
|
// skip test for windows - until feature is supported
|
||||||
if (isMac) {
|
if (isMac) {
|
||||||
it('should fail if read file fails', function(done) {
|
it('should fail if read file fails', function(done) {
|
||||||
var origFsReadFile = fs.readFile;
|
const origFsReadFile = fs.readFile;
|
||||||
|
|
||||||
fs.readFile = jest.fn(mockedReadFile);
|
fs.readFile = jest.fn(mockedReadFile);
|
||||||
|
|
||||||
@ -132,4 +131,4 @@ describe('Tests for ScreenSnippet', function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
@ -29,7 +29,7 @@ const ipcMain = {
|
|||||||
ipcEmitter.on(event, cb);
|
ipcEmitter.on(event, cb);
|
||||||
},
|
},
|
||||||
send: function (event, args) {
|
send: function (event, args) {
|
||||||
var senderEvent = {
|
const senderEvent = {
|
||||||
sender: {
|
sender: {
|
||||||
send: function (event, arg) {
|
send: function (event, arg) {
|
||||||
ipcEmitter.emit(event, arg);
|
ipcEmitter.emit(event, arg);
|
||||||
@ -45,16 +45,16 @@ const ipcRenderer = {
|
|||||||
let listeners = ipcEmitter.listeners(event);
|
let listeners = ipcEmitter.listeners(event);
|
||||||
if (listeners.length > 0) {
|
if (listeners.length > 0) {
|
||||||
let listener = listeners[0];
|
let listener = listeners[0];
|
||||||
var eventArg = {};
|
const eventArg = {};
|
||||||
listener(eventArg, args);
|
listener(eventArg, args);
|
||||||
return eventArg.returnValue;
|
return eventArg.returnValue;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
send: function(event, args) {
|
send: function(event, args) {
|
||||||
var senderEvent = {
|
const senderEvent = {
|
||||||
sender: {
|
sender: {
|
||||||
send: function(event, arg) {
|
send: function (event, arg) {
|
||||||
ipcEmitter.emit(event, arg);
|
ipcEmitter.emit(event, arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,29 +3,29 @@ const childProcess = require('child_process');
|
|||||||
|
|
||||||
let activityDetection;
|
let activityDetection;
|
||||||
|
|
||||||
describe('Tests for Activity Detection', function () {
|
describe('Tests for Activity Detection', function() {
|
||||||
|
|
||||||
var originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
|
const originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
|
||||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 90000;
|
jasmine.DEFAULT_TIMEOUT_INTERVAL = 90000;
|
||||||
|
|
||||||
beforeAll(function (done) {
|
beforeAll(function(done) {
|
||||||
childProcess.exec(`npm rebuild --target=${process.version} --build-from-source`, function (err) {
|
childProcess.exec(`npm rebuild --target=${process.version} --build-from-source`, function(err) {
|
||||||
activityDetection = require('../js/activityDetection/activityDetection.js');
|
activityDetection = require('../js/activityDetection');
|
||||||
activityDetection.setActivityWindow(900000, electron.ipcRenderer);
|
activityDetection.setActivityWindow(900000, electron.ipcRenderer);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function() {
|
||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(function (done) {
|
afterAll(function(done) {
|
||||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
|
jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return null', function () {
|
it('should return null', function() {
|
||||||
|
|
||||||
activityDetection.setActivityWindow(0, electron.ipcRenderer);
|
activityDetection.setActivityWindow(0, electron.ipcRenderer);
|
||||||
const noData = activityDetection.activityDetection();
|
const noData = activityDetection.activityDetection();
|
||||||
@ -33,17 +33,17 @@ describe('Tests for Activity Detection', function () {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should send activity event', function () {
|
it('should send activity event', function() {
|
||||||
const spy = jest.spyOn(activityDetection, 'send');
|
const spy = jest.spyOn(activityDetection, 'send');
|
||||||
|
|
||||||
expect(spy).not.toBeCalled();
|
expect(spy).not.toBeCalled();
|
||||||
|
|
||||||
activityDetection.send({systemIdleTime: 120000});
|
activityDetection.send({ systemIdleTime: 120000 });
|
||||||
expect(spy).toHaveBeenCalledWith({systemIdleTime: 120000});
|
expect(spy).toHaveBeenCalledWith({ systemIdleTime: 120000 });
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should monitor user activity', function () {
|
it('should monitor user activity', function() {
|
||||||
activityDetection.setActivityWindow(500000, electron.ipcRenderer);
|
activityDetection.setActivityWindow(500000, electron.ipcRenderer);
|
||||||
const spy = jest.spyOn(activityDetection, 'monitorUserActivity');
|
const spy = jest.spyOn(activityDetection, 'monitorUserActivity');
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ describe('Tests for Activity Detection', function () {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not send activity event as data is undefined', function () {
|
it('should not send activity event as data is undefined', function() {
|
||||||
const spy = jest.spyOn(activityDetection, 'send');
|
const spy = jest.spyOn(activityDetection, 'send');
|
||||||
|
|
||||||
expect(spy).not.toBeCalled();
|
expect(spy).not.toBeCalled();
|
||||||
@ -64,4 +64,4 @@ describe('Tests for Activity Detection', function () {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
@ -62,13 +62,13 @@ describe('read/write config tests', function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createTempUserConfig(config) {
|
function createTempUserConfig(config) {
|
||||||
var tmpDir = os.tmpdir();
|
const tmpDir = os.tmpdir();
|
||||||
userConfigDir = fs.mkdtempSync(path.join(tmpDir, 'config-'));
|
userConfigDir = fs.mkdtempSync(path.join(tmpDir, 'config-'));
|
||||||
return createTempConfigFile(path.join(userConfigDir, configFileName), config);
|
return createTempConfigFile(path.join(userConfigDir, configFileName), config);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createTempGlobalConfig(config) {
|
function createTempGlobalConfig(config) {
|
||||||
var tmpDir = os.tmpdir();
|
const tmpDir = os.tmpdir();
|
||||||
globalConfigDir = path.join(fs.mkdtempSync(path.join(tmpDir, 'config-')), 'config');
|
globalConfigDir = path.join(fs.mkdtempSync(path.join(tmpDir, 'config-')), 'config');
|
||||||
fs.mkdirSync(globalConfigDir);
|
fs.mkdirSync(globalConfigDir);
|
||||||
return createTempConfigFile(path.join(globalConfigDir, configFileName), config);
|
return createTempConfigFile(path.join(globalConfigDir, configFileName), config);
|
||||||
@ -80,15 +80,15 @@ describe('read/write config tests', function() {
|
|||||||
|
|
||||||
describe('getConfigField tests', function() {
|
describe('getConfigField tests', function() {
|
||||||
it('should fail when field not present in either user or global config', function() {
|
it('should fail when field not present in either user or global config', function() {
|
||||||
var userConfig = {
|
const userConfig = {
|
||||||
url: 'something'
|
url: 'something'
|
||||||
}
|
};
|
||||||
|
|
||||||
createTempUserConfig(userConfig);
|
createTempUserConfig(userConfig);
|
||||||
|
|
||||||
var globalConfig = {
|
const globalConfig = {
|
||||||
url: 'something-else'
|
url: 'something-else'
|
||||||
}
|
};
|
||||||
|
|
||||||
createTempGlobalConfig(globalConfig);
|
createTempGlobalConfig(globalConfig);
|
||||||
|
|
||||||
@ -98,9 +98,9 @@ describe('read/write config tests', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when field only present in user config', function() {
|
it('should succeed when field only present in user config', function() {
|
||||||
var userConfig = {
|
const userConfig = {
|
||||||
url: 'something'
|
url: 'something'
|
||||||
}
|
};
|
||||||
|
|
||||||
createTempUserConfig(userConfig);
|
createTempUserConfig(userConfig);
|
||||||
|
|
||||||
@ -110,9 +110,9 @@ describe('read/write config tests', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when field only present in global config', function() {
|
it('should succeed when field only present in global config', function() {
|
||||||
var globalConfig = {
|
const globalConfig = {
|
||||||
url: 'something-else'
|
url: 'something-else'
|
||||||
}
|
};
|
||||||
|
|
||||||
createTempGlobalConfig(globalConfig);
|
createTempGlobalConfig(globalConfig);
|
||||||
|
|
||||||
@ -122,15 +122,15 @@ describe('read/write config tests', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed and return user config field when value is in both', function() {
|
it('should succeed and return user config field when value is in both', function() {
|
||||||
var userConfig = {
|
const userConfig = {
|
||||||
url: 'something'
|
url: 'something'
|
||||||
}
|
};
|
||||||
|
|
||||||
createTempUserConfig(userConfig);
|
createTempUserConfig(userConfig);
|
||||||
|
|
||||||
var globalConfig = {
|
const globalConfig = {
|
||||||
url: 'something-else'
|
url: 'something-else'
|
||||||
}
|
};
|
||||||
|
|
||||||
createTempGlobalConfig(globalConfig);
|
createTempGlobalConfig(globalConfig);
|
||||||
|
|
||||||
@ -140,7 +140,7 @@ describe('read/write config tests', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when global config path is invalid', function() {
|
it('should fail when global config path is invalid', function() {
|
||||||
var globalConfig = {
|
const globalConfig = {
|
||||||
url: 'something-else'
|
url: 'something-else'
|
||||||
};
|
};
|
||||||
createTempGlobalConfig(globalConfig);
|
createTempGlobalConfig(globalConfig);
|
||||||
@ -155,7 +155,7 @@ describe('read/write config tests', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when user config path is invalid', function() {
|
it('should fail when user config path is invalid', function() {
|
||||||
var userConfig = {
|
const userConfig = {
|
||||||
url: 'something'
|
url: 'something'
|
||||||
};
|
};
|
||||||
createTempUserConfig(userConfig);
|
createTempUserConfig(userConfig);
|
||||||
@ -170,12 +170,12 @@ describe('read/write config tests', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should read cached user config value rather than reading file from disk again', function(done) {
|
it('should read cached user config value rather than reading file from disk again', function(done) {
|
||||||
var userConfig = {
|
const userConfig = {
|
||||||
url: 'qa4.symphony.com'
|
url: 'qa4.symphony.com'
|
||||||
};
|
};
|
||||||
createTempUserConfig(userConfig);
|
createTempUserConfig(userConfig);
|
||||||
|
|
||||||
var userConfig2 = {
|
const userConfig2 = {
|
||||||
url: 'qa5.symphony.com'
|
url: 'qa5.symphony.com'
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -193,12 +193,12 @@ describe('read/write config tests', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should read cache global config value rather than reading file from disk again', function(done) {
|
it('should read cache global config value rather than reading file from disk again', function(done) {
|
||||||
var globalConfig = {
|
const globalConfig = {
|
||||||
url: 'qa8.symphony.com'
|
url: 'qa8.symphony.com'
|
||||||
};
|
};
|
||||||
createTempGlobalConfig(globalConfig);
|
createTempGlobalConfig(globalConfig);
|
||||||
|
|
||||||
var globalConfig2 = {
|
const globalConfig2 = {
|
||||||
url: 'qa9.symphony.com'
|
url: 'qa9.symphony.com'
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -220,7 +220,7 @@ describe('read/write config tests', function() {
|
|||||||
describe('updateConfigField tests', function() {
|
describe('updateConfigField tests', function() {
|
||||||
|
|
||||||
it('should succeed and overwrite existing field', function() {
|
it('should succeed and overwrite existing field', function() {
|
||||||
var userConfig = {
|
const userConfig = {
|
||||||
url: 'something'
|
url: 'something'
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -235,7 +235,7 @@ describe('read/write config tests', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed and add new field', function() {
|
it('should succeed and add new field', function() {
|
||||||
var userConfig = {
|
const userConfig = {
|
||||||
url: 'something'
|
url: 'something'
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -252,7 +252,7 @@ describe('read/write config tests', function() {
|
|||||||
|
|
||||||
it('should fail to update if invalid field name', function() {
|
it('should fail to update if invalid field name', function() {
|
||||||
|
|
||||||
var userConfig = {
|
const userConfig = {
|
||||||
url: 'something'
|
url: 'something'
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -277,7 +277,7 @@ describe('read/write config tests', function() {
|
|||||||
|
|
||||||
it('should throw error if fieldName is not defined', function() {
|
it('should throw error if fieldName is not defined', function() {
|
||||||
|
|
||||||
var userConfig = {
|
const userConfig = {
|
||||||
url: 'something'
|
url: 'something'
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -291,7 +291,7 @@ describe('read/write config tests', function() {
|
|||||||
|
|
||||||
it('should throw error if config is not defined', function() {
|
it('should throw error if config is not defined', function() {
|
||||||
|
|
||||||
var userConfig = {
|
const userConfig = {
|
||||||
url: 'something'
|
url: 'something'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
4
tests/fixtures/snippet/snippet-base64.js
vendored
4
tests/fixtures/snippet/snippet-base64.js
vendored
@ -1,5 +1,5 @@
|
|||||||
// base64 conversion of file ScreenSnippet.jpeg
|
// base64 conversion of file ScreenSnippet.jpeg
|
||||||
const base64ScreenSnippet =
|
const base64ScreenSnippet =
|
||||||
"/9j/4AAQSkZJRgABAQEASABIAAD/4QB0RXhpZgAATU0AKgAAAAgABAEaAAUAAAABAAAAPgEbAAUAAAABAAAARgEoAAMAAAABAAIAAIdpAAQAAAABAAAATgAAAAAAAABIAAAAAQAAAEgAAAABAAKgAgAEAAAAAQAAAEOgAwAEAAAAAQAAADsAAAAA/+0AOFBob3Rvc2hvcCAzLjAAOEJJTQQEAAAAAAAAOEJJTQQlAAAAAAAQ1B2M2Y8AsgTpgAmY7PhCfv/iAoRJQ0NfUFJPRklMRQABAQAAAnRhcHBsBAAAAG1udHJSR0IgWFlaIAfcAAsADAASADoAF2Fjc3BBUFBMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD21gABAAAAANMtYXBwbGZJ+dk8hXeftAZKmR46dCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2Rlc2MAAAEIAAAAY2RzY20AAAFsAAA" + "ALGNwcnQAAAGYAAAALXd0cHQAAAHIAAAAFHJYWVoAAAHcAAAAFGdYWVoAAAHwAAAAFGJYWVoAAAIEAAAAFHJUUkMAAAIYAAAAEGJUUkMAAAIoAAAAEGdUUkMAAAI4AAAAEGNoYWQAAAJIAAAALGRlc2MAAAAAAAAACUhEIDcwOS1BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAABAAAAAcAEgARAAgADcAMAA5AC0AQXRleHQAAAAAQ29weXJpZ2h0IEFwcGxlIENvbXB1dGVyLCBJbmMuLCAyMDEwAAAAAFhZWiAAAAAAAADzUgABAAAAARbPWFlaIAAAAAAAAG+hAAA5IwAAA4xYWVogAAAAAAAAYpYAALe8AAAYylhZWiAAAA" + "AAAAAkngAADzsAALbOcGFyYQAAAAAAAAAAAAH2BHBhcmEAAAAAAAAAAAAB9gRwYXJhAAAAAAAAAAAAAfYEc2YzMgAAAAAAAQxCAAAF3v//8yYAAAeSAAD9kf//+6L///2jAAAD3AAAwGz/wAARCAA7AEMDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFB" + "gcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9sAQwACAgICAgIDAgIDBQMDAwUGBQUFBQYIBgYGBgYICggICAgICAoKCgoKCgoKDAwMDAwMDg4ODg4PDw8PDw8PDw8P/9sAQwECAgIEBAQHBAQHEAsJCxAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ/90ABAAF/9oADAMBAAIRAxEAPwD8u6KK9e+H3gqG9Rde1ePfDn9xEw4b" + "H8bDuPQd+vTr7+CwU69RU4Hw3EXEOHyzCyxWIei0S6t9kcZongvX9dRZrWDyrduksp2qfp1J/AYrt4vhFcFczaoqN6LEWH5lh/KvbQAAABgClr7ahw3h4r31zP8Arsfznmfi9m1abeHapx6JJN/NyT/BI+RviL8CfFWqQW02gzwXrW3mZjYmJ237cbd2V7d2FfJ+r6NqugXz6ZrVpJZXUf3o5VKnB6EZ6g9iODX601xfjjwHoPj3SH0zWYgJAD5NwoHmwv2Kn09V6H8jXnZlwnTmnKg7Pt0PouFvGvFUqkaWZxU4fzJWkvOy0a8rJ/kflvRXR+LPDGpeDtfu/D2qria1bAYZ2yIeVdc9mHP6Hmucr8+qU3GTjJWaP6dw2IhWpxq0neMldPumFFFFQbH/0PzL0mwbVNUtNOU4+0yKhPoCeT+A5r67hhit4Y7eBQkcShVUdAqjAFfMPgIqPGOmh+haT8/LbH619R1+l8LUl7K" + "c+t7f195/KfjZjJvGUMP9lR5vm21/7aFeq/CzwVpPjT/hL/7WeVP7C8O6hqsHlMFzPa7NgfIOV+Y5Awfeua8FS+AodWkb4iW2o3Om+SwRdMlhhmE25dpYzI6lNu7IABzjnqD9d/Bm7/Z9f/hOv+Ed03xLFt8K6mbz7VdWj7rMeX5qxbIVxKeNpbKjnINexj8TKEHyxfqfnvDGUU8RXg6lSNtfdbd9n5fqfClFe46xefs4NpN4ug6X4pj1IwuLZri8smhE207DIFgDFA2NwBBI6Eda8OrspVXL7LXqeFjcGqLSVSMr/wAt/wBUj5Z/ae8MxXOiad4shQefZy/ZpSOpilyVz/usOP8AeNfFNfox8fvL/wCFVaxv+9uttv18+P8Apmvznr824soqOLuuqT/Nfof1h4LY6dbJeSf2JyivSyl+cmFFFFfMn62f/9H8xdO1BtJ1Sz1RBn7NKrkDuoPI/EcV9gwTxXMEdzAweKVQ6s" + "OhVhkH8RXxk67lIr1P4c+OodNVfDutybIM/uJmPCZ/gY9hnoe3TpX3HDuYxpTdKbsn+f8AwT8F8WuE6uNoQxmGjedO6aW7j5ej6dmz3+vTfhp45sfA/wDwlf263kuP7f0C+0iLy8fJLd7Nrtkj5Rt5xzXmIIYBlOQehpa+4qU1OPLLY/mrCYqdCoqtPdf8MFFFcX448eaD4C0h9T1mUGQg+TbqR5sz9go9PVug/IUVasYRc5uyQ8FgquIqxoUIuUpaJI8N/ae8TRW2iad4ThcefeS/aZQOoiiyFz/vMeP9018U10fizxPqXjHX7vxDqrZmumyFGdsaDhUXPZRx+p5rnK/Is4x/1nESqLbp6H9wcD8N/wBlZbTwktZby/xPf7tvkFFFFeYfXH//0vy7qvNCHFWKK9Q8RM2ND8a+J/DaLb2dwJrZekMw3oB6DoR9AQK7mL41Xipi40dHb1WYqPyKN/OvK2AqEquelehQzXEUl" + "ywm7ff+Z8tmXA2U4ybqYjDpye7V4t+vK1f5mv4++Pni2wggh0O2t7A3G/MjAzOu3GNu7C9+6mvljV9Z1XX759T1q7kvbqT70krFmwOgGegHYDgV9If8I3ouvD/ibW3n+R9z53XG7r90r6DrTv8AhXHgz/oH/wDkaX/4uvPx2Mr13+8ndf10PcyHh3Lsvj/slFRb3a1f3vX8T5aor6l/4Vx4M/6B/wD5Gl/+Lo/4Vx4M/wCgf/5Gl/8Ai64PZM+i9sj5aor6l/4Vx4M/6B//AJGl/wDi6P8AhXHgz/oH/wDkaX/4uj2TD2yP/9k="
|
"/9j/4AAQSkZJRgABAQEASABIAAD/4QB0RXhpZgAATU0AKgAAAAgABAEaAAUAAAABAAAAPgEbAAUAAAABAAAARgEoAAMAAAABAAIAAIdpAAQAAAABAAAATgAAAAAAAABIAAAAAQAAAEgAAAABAAKgAgAEAAAAAQAAAEOgAwAEAAAAAQAAADsAAAAA/+0AOFBob3Rvc2hvcCAzLjAAOEJJTQQEAAAAAAAAOEJJTQQlAAAAAAAQ1B2M2Y8AsgTpgAmY7PhCfv/iAoRJQ0NfUFJPRklMRQABAQAAAnRhcHBsBAAAAG1udHJSR0IgWFlaIAfcAAsADAASADoAF2Fjc3BBUFBMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD21gABAAAAANMtYXBwbGZJ+dk8hXeftAZKmR46dCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2Rlc2MAAAEIAAAAY2RzY20AAAFsAAA" + "ALGNwcnQAAAGYAAAALXd0cHQAAAHIAAAAFHJYWVoAAAHcAAAAFGdYWVoAAAHwAAAAFGJYWVoAAAIEAAAAFHJUUkMAAAIYAAAAEGJUUkMAAAIoAAAAEGdUUkMAAAI4AAAAEGNoYWQAAAJIAAAALGRlc2MAAAAAAAAACUhEIDcwOS1BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAABAAAAAcAEgARAAgADcAMAA5AC0AQXRleHQAAAAAQ29weXJpZ2h0IEFwcGxlIENvbXB1dGVyLCBJbmMuLCAyMDEwAAAAAFhZWiAAAAAAAADzUgABAAAAARbPWFlaIAAAAAAAAG+hAAA5IwAAA4xYWVogAAAAAAAAYpYAALe8AAAYylhZWiAAAA" + "AAAAAkngAADzsAALbOcGFyYQAAAAAAAAAAAAH2BHBhcmEAAAAAAAAAAAAB9gRwYXJhAAAAAAAAAAAAAfYEc2YzMgAAAAAAAQxCAAAF3v//8yYAAAeSAAD9kf//+6L///2jAAAD3AAAwGz/wAARCAA7AEMDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFB" + "gcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9sAQwACAgICAgIDAgIDBQMDAwUGBQUFBQYIBgYGBgYICggICAgICAoKCgoKCgoKDAwMDAwMDg4ODg4PDw8PDw8PDw8P/9sAQwECAgIEBAQHBAQHEAsJCxAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ/90ABAAF/9oADAMBAAIRAxEAPwD8u6KK9e+H3gqG9Rde1ePfDn9xEw4b" + "H8bDuPQd+vTr7+CwU69RU4Hw3EXEOHyzCyxWIei0S6t9kcZongvX9dRZrWDyrduksp2qfp1J/AYrt4vhFcFczaoqN6LEWH5lh/KvbQAAABgClr7ahw3h4r31zP8Arsfznmfi9m1abeHapx6JJN/NyT/BI+RviL8CfFWqQW02gzwXrW3mZjYmJ237cbd2V7d2FfJ+r6NqugXz6ZrVpJZXUf3o5VKnB6EZ6g9iODX601xfjjwHoPj3SH0zWYgJAD5NwoHmwv2Kn09V6H8jXnZlwnTmnKg7Pt0PouFvGvFUqkaWZxU4fzJWkvOy0a8rJ/kflvRXR+LPDGpeDtfu/D2qria1bAYZ2yIeVdc9mHP6Hmucr8+qU3GTjJWaP6dw2IhWpxq0neMldPumFFFFQbH/0PzL0mwbVNUtNOU4+0yKhPoCeT+A5r67hhit4Y7eBQkcShVUdAqjAFfMPgIqPGOmh+haT8/LbH619R1+l8LUl7K" + "c+t7f195/KfjZjJvGUMP9lR5vm21/7aFeq/CzwVpPjT/hL/7WeVP7C8O6hqsHlMFzPa7NgfIOV+Y5Awfeua8FS+AodWkb4iW2o3Om+SwRdMlhhmE25dpYzI6lNu7IABzjnqD9d/Bm7/Z9f/hOv+Ed03xLFt8K6mbz7VdWj7rMeX5qxbIVxKeNpbKjnINexj8TKEHyxfqfnvDGUU8RXg6lSNtfdbd9n5fqfClFe46xefs4NpN4ug6X4pj1IwuLZri8smhE207DIFgDFA2NwBBI6Eda8OrspVXL7LXqeFjcGqLSVSMr/wAt/wBUj5Z/ae8MxXOiad4shQefZy/ZpSOpilyVz/usOP8AeNfFNfox8fvL/wCFVaxv+9uttv18+P8Apmvznr824soqOLuuqT/Nfof1h4LY6dbJeSf2JyivSyl+cmFFFFfMn62f/9H8xdO1BtJ1Sz1RBn7NKrkDuoPI/EcV9gwTxXMEdzAweKVQ6s" + "OhVhkH8RXxk67lIr1P4c+OodNVfDutybIM/uJmPCZ/gY9hnoe3TpX3HDuYxpTdKbsn+f8AwT8F8WuE6uNoQxmGjedO6aW7j5ej6dmz3+vTfhp45sfA/wDwlf263kuP7f0C+0iLy8fJLd7Nrtkj5Rt5xzXmIIYBlOQehpa+4qU1OPLLY/mrCYqdCoqtPdf8MFFFcX448eaD4C0h9T1mUGQg+TbqR5sz9go9PVug/IUVasYRc5uyQ8FgquIqxoUIuUpaJI8N/ae8TRW2iad4ThcefeS/aZQOoiiyFz/vMeP9018U10fizxPqXjHX7vxDqrZmumyFGdsaDhUXPZRx+p5rnK/Is4x/1nESqLbp6H9wcD8N/wBlZbTwktZby/xPf7tvkFFFFeYfXH//0vy7qvNCHFWKK9Q8RM2ND8a+J/DaLb2dwJrZekMw3oB6DoR9AQK7mL41Xipi40dHb1WYqPyKN/OvK2AqEquelehQzXEUl" + "ywm7ff+Z8tmXA2U4ybqYjDpye7V4t+vK1f5mv4++Pni2wggh0O2t7A3G/MjAzOu3GNu7C9+6mvljV9Z1XX759T1q7kvbqT70krFmwOgGegHYDgV9If8I3ouvD/ibW3n+R9z53XG7r90r6DrTv8AhXHgz/oH/wDkaX/4uvPx2Mr13+8ndf10PcyHh3Lsvj/slFRb3a1f3vX8T5aor6l/4Vx4M/6B/wD5Gl/+Lo/4Vx4M/wCgf/5Gl/8Ai64PZM+i9sj5aor6l/4Vx4M/6B//AJGl/wDi6P8AhXHgz/oH/wDkaX/4uj2TD2yP/9k=";
|
||||||
|
|
||||||
module.exports = base64ScreenSnippet
|
module.exports = base64ScreenSnippet;
|
||||||
|
@ -21,7 +21,6 @@ describe('Tests for Bring to front', () => {
|
|||||||
app.stop().then(() => {
|
app.stop().then(() => {
|
||||||
done();
|
done();
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.log(err);
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ describe('Tests for clipboard', () => {
|
|||||||
app.stop().then(() => {
|
app.stop().then(() => {
|
||||||
done();
|
done();
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.log(err);
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,6 @@ describe('Tests for Close', () => {
|
|||||||
app.stop().then(() => {
|
app.stop().then(() => {
|
||||||
done();
|
done();
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.log(err);
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -19,7 +19,6 @@ describe('Tests for Full screen', () => {
|
|||||||
return app.startApplication().then((startedApp) => {
|
return app.startApplication().then((startedApp) => {
|
||||||
app = startedApp;
|
app = startedApp;
|
||||||
getConfigPath().then((config) => {
|
getConfigPath().then((config) => {
|
||||||
console.log(config);
|
|
||||||
configPath = config;
|
configPath = config;
|
||||||
done();
|
done();
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
@ -54,7 +53,6 @@ describe('Tests for Full screen', () => {
|
|||||||
app.stop().then(() => {
|
app.stop().then(() => {
|
||||||
done();
|
done();
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.log(err);
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -99,7 +97,6 @@ describe('Tests for Full screen', () => {
|
|||||||
app.browserWindow.focus();
|
app.browserWindow.focus();
|
||||||
return app.browserWindow.setAlwaysOnTop(true).then(() => {
|
return app.browserWindow.setAlwaysOnTop(true).then(() => {
|
||||||
return app.browserWindow.isAlwaysOnTop().then((isOnTop) => {
|
return app.browserWindow.isAlwaysOnTop().then((isOnTop) => {
|
||||||
console.log(isOnTop);
|
|
||||||
expect(isOnTop).toBeTruthy();
|
expect(isOnTop).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -19,7 +19,6 @@ describe('Tests for Minimize on Close', () => {
|
|||||||
return app.startApplication().then((startedApp) => {
|
return app.startApplication().then((startedApp) => {
|
||||||
app = startedApp;
|
app = startedApp;
|
||||||
getConfigPath().then((config) => {
|
getConfigPath().then((config) => {
|
||||||
console.log(config);
|
|
||||||
configPath = config;
|
configPath = config;
|
||||||
done();
|
done();
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
@ -54,7 +53,6 @@ describe('Tests for Minimize on Close', () => {
|
|||||||
app.stop().then(() => {
|
app.stop().then(() => {
|
||||||
done();
|
done();
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.log(err);
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -99,7 +97,6 @@ describe('Tests for Minimize on Close', () => {
|
|||||||
app.browserWindow.focus();
|
app.browserWindow.focus();
|
||||||
return app.browserWindow.setAlwaysOnTop(true).then(() => {
|
return app.browserWindow.setAlwaysOnTop(true).then(() => {
|
||||||
return app.browserWindow.isAlwaysOnTop().then((isOnTop) => {
|
return app.browserWindow.isAlwaysOnTop().then((isOnTop) => {
|
||||||
console.log(isOnTop);
|
|
||||||
expect(isOnTop).toBeTruthy();
|
expect(isOnTop).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -23,7 +23,6 @@ describe('Tests for Notification position', () => {
|
|||||||
app.stop().then(() => {
|
app.stop().then(() => {
|
||||||
done();
|
done();
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.log(err);
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@ class App {
|
|||||||
return this.app.start().then((app) => {
|
return this.app.start().then((app) => {
|
||||||
return app;
|
return app;
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.log(err);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,6 @@ describe('Tests for spellChecker', () => {
|
|||||||
app.stop().then(() => {
|
app.stop().then(() => {
|
||||||
done();
|
done();
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.log(err);
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,6 @@ describe('Tests for Zoom in and Zoom out', () => {
|
|||||||
app.stop().then(() => {
|
app.stop().then(() => {
|
||||||
done();
|
done();
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.log(err);
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -111,7 +110,7 @@ describe('Tests for Zoom in and Zoom out', () => {
|
|||||||
robot.keyToggle('0', 'up');
|
robot.keyToggle('0', 'up');
|
||||||
robot.keyToggle('command', 'up');
|
robot.keyToggle('command', 'up');
|
||||||
|
|
||||||
for (var i = 0; i < 4; i++) {
|
for (let i = 0; i < 4; i++) {
|
||||||
robot.keyToggle('+', 'down', ['command']);
|
robot.keyToggle('+', 'down', ['command']);
|
||||||
}
|
}
|
||||||
robot.keyToggle('+', 'up');
|
robot.keyToggle('+', 'up');
|
||||||
@ -134,7 +133,7 @@ describe('Tests for Zoom in and Zoom out', () => {
|
|||||||
robot.keyToggle('0', 'up');
|
robot.keyToggle('0', 'up');
|
||||||
robot.keyToggle('control', 'up');
|
robot.keyToggle('control', 'up');
|
||||||
|
|
||||||
for (var i = 0; i < 4; i++) {
|
for (let i = 0; i < 4; i++) {
|
||||||
robot.keyToggle('+', 'down', ['control', 'shift']);
|
robot.keyToggle('+', 'down', ['control', 'shift']);
|
||||||
}
|
}
|
||||||
robot.keyToggle('+', 'up');
|
robot.keyToggle('+', 'up');
|
||||||
@ -159,7 +158,7 @@ describe('Tests for Zoom in and Zoom out', () => {
|
|||||||
robot.keyToggle('0', 'up');
|
robot.keyToggle('0', 'up');
|
||||||
robot.keyToggle('command', 'up');
|
robot.keyToggle('command', 'up');
|
||||||
|
|
||||||
for (var i = 0; i < 4; i++) {
|
for (let i = 0; i < 4; i++) {
|
||||||
robot.keyToggle('-', 'down', ['command']);
|
robot.keyToggle('-', 'down', ['command']);
|
||||||
}
|
}
|
||||||
robot.keyToggle('-', 'up');
|
robot.keyToggle('-', 'up');
|
||||||
@ -183,7 +182,7 @@ describe('Tests for Zoom in and Zoom out', () => {
|
|||||||
robot.keyToggle('0', 'up');
|
robot.keyToggle('0', 'up');
|
||||||
robot.keyToggle('control', 'up');
|
robot.keyToggle('control', 'up');
|
||||||
|
|
||||||
for (var i = 0; i < 4; i++) {
|
for (let i = 0; i < 4; i++) {
|
||||||
robot.keyToggle('-', 'down', ['control']);
|
robot.keyToggle('-', 'down', ['control']);
|
||||||
}
|
}
|
||||||
robot.keyToggle('-', 'up');
|
robot.keyToggle('-', 'up');
|
||||||
|
@ -2,27 +2,27 @@ const getCmdLineArg = require('../../js/utils/getCmdLineArg.js');
|
|||||||
|
|
||||||
describe('getCmdLineArg tests', function() {
|
describe('getCmdLineArg tests', function() {
|
||||||
it('should return no exact match', function() {
|
it('should return no exact match', function() {
|
||||||
var result = getCmdLineArg([ 'hello.exe', '--arg1', '--arg2'], '--arg', true);
|
const result = getCmdLineArg(['hello.exe', '--arg1', '--arg2'], '--arg', true);
|
||||||
expect(result).toBe(null);
|
expect(result).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return exact match only', function() {
|
it('should return exact match only', function() {
|
||||||
var result = getCmdLineArg([ 'hello.exe', '--arg1', '--arg2'], '--arg2', true);
|
const result = getCmdLineArg(['hello.exe', '--arg1', '--arg2'], '--arg2', true);
|
||||||
expect(result).toBe('--arg2');
|
expect(result).toBe('--arg2');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return starts with match', function() {
|
it('should return starts with match', function() {
|
||||||
var result = getCmdLineArg([ 'hello.exe', '--hello=test', '--arg2'], '--hello=');
|
const result = getCmdLineArg(['hello.exe', '--hello=test', '--arg2'], '--hello=', false);
|
||||||
expect(result).toBe('--hello=test');
|
expect(result).toBe('--hello=test');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return no match for starts with', function() {
|
it('should return no match for starts with', function() {
|
||||||
var result = getCmdLineArg([ 'hello.exe', '--hello=test', '--arg2'], '--help=');
|
const result = getCmdLineArg(['hello.exe', '--hello=test', '--arg2'], '--help=', false);
|
||||||
expect(result).toBe(null);
|
expect(result).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return no match invalid argv given', function() {
|
it('should return no match invalid argv given', function() {
|
||||||
var result = getCmdLineArg('invalid argv', '--help=');
|
const result = getCmdLineArg('invalid argv', '--help=', false);
|
||||||
expect(result).toBe(null);
|
expect(result).toBe(null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -2,9 +2,9 @@ const getGuid = require('../../js/utils/getGuid.js');
|
|||||||
|
|
||||||
describe('guid tests', function() {
|
describe('guid tests', function() {
|
||||||
it('should have valid length', function() {
|
it('should have valid length', function() {
|
||||||
var guid = getGuid();
|
const guid = getGuid();
|
||||||
expect(guid.length).toBe(36);
|
expect(guid.length).toBe(36);
|
||||||
var parts = guid.split('-');
|
const parts = guid.split('-');
|
||||||
expect(parts.length).toBe(5);
|
expect(parts.length).toBe(5);
|
||||||
expect(parts[0].length).toBe(8);
|
expect(parts[0].length).toBe(8);
|
||||||
expect(parts[1].length).toBe(4);
|
expect(parts[1].length).toBe(4);
|
||||||
@ -14,9 +14,9 @@ describe('guid tests', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should only contains hex chars', function() {
|
it('should only contains hex chars', function() {
|
||||||
for(var i = 0; i < 100; i++) {
|
for(let i = 0; i < 100; i++) {
|
||||||
var guid = getGuid();
|
const guid = getGuid();
|
||||||
var parts = guid.split('-');
|
const parts = guid.split('-');
|
||||||
parts.forEach(function(part) {
|
parts.forEach(function(part) {
|
||||||
expect(/^([A-Fa-f0-9]{2})+$/.test(part)).toBe(true);
|
expect(/^([A-Fa-f0-9]{2})+$/.test(part)).toBe(true);
|
||||||
});
|
});
|
||||||
|
@ -33,12 +33,12 @@ describe('isInDisplayBounds should', function() {
|
|||||||
}
|
}
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
var rect = {
|
const rect = {
|
||||||
x: 1,
|
x: 1,
|
||||||
y: 1,
|
y: 1,
|
||||||
width: 90,
|
width: 90,
|
||||||
height: 90
|
height: 90
|
||||||
}
|
};
|
||||||
|
|
||||||
expect(isInDisplayBounds(rect)).toBe(true);
|
expect(isInDisplayBounds(rect)).toBe(true);
|
||||||
});
|
});
|
||||||
@ -53,12 +53,12 @@ describe('isInDisplayBounds should', function() {
|
|||||||
}
|
}
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
var rect = {
|
const rect = {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
width: 100,
|
width: 100,
|
||||||
height: 100
|
height: 100
|
||||||
}
|
};
|
||||||
|
|
||||||
expect(isInDisplayBounds(rect)).toBe(true);
|
expect(isInDisplayBounds(rect)).toBe(true);
|
||||||
});
|
});
|
||||||
@ -73,12 +73,12 @@ describe('isInDisplayBounds should', function() {
|
|||||||
}
|
}
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
var rect = {
|
const rect = {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
width: 100,
|
width: 100,
|
||||||
height: 100
|
height: 100
|
||||||
}
|
};
|
||||||
|
|
||||||
expect(isInDisplayBounds(rect)).toBe(true);
|
expect(isInDisplayBounds(rect)).toBe(true);
|
||||||
});
|
});
|
||||||
@ -100,15 +100,15 @@ describe('isInDisplayBounds should', function() {
|
|||||||
x: 100,
|
x: 100,
|
||||||
y: 0
|
y: 0
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
createMockDisplay([ display1, display2 ]);
|
createMockDisplay([ display1, display2 ]);
|
||||||
|
|
||||||
var rect = {
|
const rect = {
|
||||||
x: 110,
|
x: 110,
|
||||||
y: 0,
|
y: 0,
|
||||||
width: 50,
|
width: 50,
|
||||||
height: 50
|
height: 50
|
||||||
}
|
};
|
||||||
|
|
||||||
expect(isInDisplayBounds(rect)).toBe(true);
|
expect(isInDisplayBounds(rect)).toBe(true);
|
||||||
});
|
});
|
||||||
@ -123,12 +123,12 @@ describe('isInDisplayBounds should', function() {
|
|||||||
}
|
}
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
var rect = {
|
const rect = {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
width: 100,
|
width: 100,
|
||||||
height: 101
|
height: 101
|
||||||
}
|
};
|
||||||
|
|
||||||
expect(isInDisplayBounds(rect)).toBe(false);
|
expect(isInDisplayBounds(rect)).toBe(false);
|
||||||
});
|
});
|
||||||
@ -149,15 +149,15 @@ describe('isInDisplayBounds should', function() {
|
|||||||
x: 100,
|
x: 100,
|
||||||
y: 0
|
y: 0
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
createMockDisplay([ display1, display2 ]);
|
createMockDisplay([ display1, display2 ]);
|
||||||
|
|
||||||
var rect = {
|
const rect = {
|
||||||
x: 50,
|
x: 50,
|
||||||
y: 50,
|
y: 50,
|
||||||
width: 75,
|
width: 75,
|
||||||
height: 25
|
height: 25
|
||||||
}
|
};
|
||||||
|
|
||||||
expect(isInDisplayBounds(rect)).toBe(false);
|
expect(isInDisplayBounds(rect)).toBe(false);
|
||||||
});
|
});
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
const throttle = require('../../js/utils/throttle.js');
|
const throttle = require('../../js/utils/throttle.js');
|
||||||
|
|
||||||
describe('throttle tests', function() {
|
describe('throttle tests', function() {
|
||||||
var now, origNow;
|
let now, origNow;
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
origNow = Date.now;
|
origNow = Date.now;
|
||||||
// mock date func
|
// mock date func
|
||||||
|
Loading…
Reference in New Issue
Block a user