.
23
.gitignore
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
app/node_modules
|
||||
app/src/daemonInstaller.generated.js
|
||||
app/assets/webpack
|
||||
app/elements-native.node
|
||||
|
||||
node_modules
|
||||
typings
|
||||
|
||||
build/files.wxs
|
||||
native/windows/build
|
||||
native/mac/build
|
||||
native/linux/build
|
||||
native/build
|
||||
dist
|
||||
driver/build
|
||||
driver/obj
|
||||
|
||||
*.xcworkspacedata
|
||||
*.xcuserstate
|
||||
*.wixpdb
|
||||
|
||||
coverage
|
||||
.nyc_output
|
108
.gitlab-ci.yml
Normal file
|
@ -0,0 +1,108 @@
|
|||
cache:
|
||||
untracked: true
|
||||
key: "$CI_BUILD_REF_NAME"
|
||||
paths:
|
||||
- app/node_modules
|
||||
- node_modules
|
||||
- typings
|
||||
|
||||
stages:
|
||||
- Build
|
||||
- Test
|
||||
- Package
|
||||
- Upload
|
||||
|
||||
Build:
|
||||
stage: Build
|
||||
script:
|
||||
- npm prune
|
||||
- npm install
|
||||
- cd app; npm prune && npm install; cd ..
|
||||
- ./node_modules/.bin/typings install
|
||||
tags:
|
||||
- Linux
|
||||
artifacts:
|
||||
paths:
|
||||
- node_modules
|
||||
- typings
|
||||
- app
|
||||
|
||||
Test:
|
||||
stage: Test
|
||||
dependencies:
|
||||
- Build
|
||||
script:
|
||||
- apt-get install -y xvfb libxtst6 libxss1 libgconf2-4 libnss3 libasound2
|
||||
- xvfb-run -a make coverage
|
||||
tags:
|
||||
- Linux
|
||||
|
||||
Windows package:
|
||||
stage: Package
|
||||
dependencies:
|
||||
- Build
|
||||
script:
|
||||
- call npm install
|
||||
- call npm install webpack # regenerate the .cmd launcher
|
||||
- cd app
|
||||
- call npm install
|
||||
- cd ..
|
||||
- call ./node_modules/.bin/webpack.cmd --progress
|
||||
- call make package-windows
|
||||
- call copy dist\Elements-Electron.exe Elements-Windows-%CI_BUILD_REF_NAME%.exe
|
||||
artifacts:
|
||||
name: Elements-Windows-%CI_BUILD_REF_NAME%
|
||||
paths:
|
||||
- Elements-Windows-%CI_BUILD_REF_NAME%.exe
|
||||
tags:
|
||||
- Windows
|
||||
|
||||
macOS package:
|
||||
stage: Package
|
||||
dependencies:
|
||||
- Build
|
||||
script:
|
||||
- npm install
|
||||
- rm -rf node_modules/electron-macos-sign || true
|
||||
- cp -r node_modules/electron-osx-sign node_modules/electron-macos-sign
|
||||
- cd app; npm install; cd ..
|
||||
- ./node_modules/.bin/webpack --progress
|
||||
- security unlock-keychain -p rjvg login.keychain
|
||||
- make package-mac
|
||||
- cp dist/Elements-Electron.pkg ./Elements-macOS-$CI_BUILD_REF_NAME.pkg
|
||||
artifacts:
|
||||
name: Elements-macOS-$CI_BUILD_REF_NAME
|
||||
paths:
|
||||
- Elements-macOS-$CI_BUILD_REF_NAME.pkg
|
||||
tags:
|
||||
- macOS
|
||||
|
||||
Linux package:
|
||||
stage: Package
|
||||
dependencies:
|
||||
- Build
|
||||
script:
|
||||
- npm install
|
||||
- cd app; npm install; cd ..
|
||||
- ./node_modules/.bin/webpack --progress
|
||||
- make build-linux
|
||||
- cp dist/ELEMENTS*.AppImage ./Elements-Linux-$CI_BUILD_REF_NAME.AppImage
|
||||
artifacts:
|
||||
name: Elements-Linux-$CI_BUILD_REF_NAME
|
||||
paths:
|
||||
- Elements-Linux-$CI_BUILD_REF_NAME.AppImage
|
||||
tags:
|
||||
- Linux
|
||||
|
||||
Upload packages:
|
||||
stage: Upload
|
||||
dependencies:
|
||||
- Windows package
|
||||
- macOS package
|
||||
- Linux package
|
||||
script:
|
||||
- scp Elements-Windows-$CI_BUILD_REF_NAME.exe root@cloud.elements.tv:/mnt/elements/www/clients/
|
||||
- scp Elements-macOS-$CI_BUILD_REF_NAME.pkg root@cloud.elements.tv:/mnt/elements/www/clients/
|
||||
- scp Elements-Linux-$CI_BUILD_REF_NAME.AppImage root@cloud.elements.tv:/mnt/elements/www/clients/
|
||||
tags:
|
||||
- Local
|
97
Makefile
Normal file
|
@ -0,0 +1,97 @@
|
|||
MAC_WS="/tmp/elements-build"
|
||||
MAC_OUTPUT="./dist/Elements-Electron.pkg"
|
||||
FULL_VERSION=$(shell python -c 'import subprocess; v = subprocess.check_output("git describe --tags --long", shell=True).strip()[1:]; print(v.split("-0-g")[0])')
|
||||
SHORT_VERSION=$(shell python -c 'import subprocess; v = subprocess.check_output("git describe --tags --long", shell=True).strip()[1:].split("-")[0]; print(v)')
|
||||
|
||||
all: run
|
||||
|
||||
run:
|
||||
DEV=1 ./node_modules/.bin/electron ./app
|
||||
|
||||
lint:
|
||||
tslint -c tslint.json app/src/*.ts app/src/**/*.ts
|
||||
|
||||
build:
|
||||
DEV=1 ./node_modules/.bin/webpack --progress
|
||||
|
||||
watch:
|
||||
DEV=1 ./node_modules/.bin/webpack --progress -w
|
||||
|
||||
build-native-windows:
|
||||
echo :: Building native extensions
|
||||
rm -r ./native/windows/build || true
|
||||
cd native/windows && node-gyp rebuild --target=1.4.12 --arch=x64 --dist-url=https://atom.io/download/atom-shell
|
||||
mkdir native/build || true
|
||||
cp ./native/windows/build/Release/elements-native.node ./app/
|
||||
|
||||
build-native-mac:
|
||||
echo :: Building native extensions
|
||||
rm -r ./native/mac/build || true
|
||||
cd native/mac && node-gyp rebuild --target=1.4.12 --arch=x64 --dist-url=https://atom.io/download/atom-shell
|
||||
mkdir native/build || true
|
||||
cp ./native/mac/build/Release/elements-native.node ./app/
|
||||
|
||||
build-native-linux:
|
||||
echo :: Building native extensions
|
||||
rm -r ./native/linux/build || true
|
||||
cd native/linux && node-gyp rebuild --target=1.4.12 --arch=x64 --dist-url=https://atom.io/download/atom-shell
|
||||
mkdir native/build || true
|
||||
cp ./native/linux/build/Release/elements-native.node ./app/
|
||||
|
||||
build-windows: build-native-windows
|
||||
echo :: Building application
|
||||
./node_modules/.bin/build --dir --win --em.version=$(FULL_VERSION)
|
||||
cp ./app/assets/img/disk.ico dist/win-unpacked/
|
||||
|
||||
build-mac: build-native-mac
|
||||
echo :: Building application
|
||||
./node_modules/.bin/build --dir --mac --em.version=$(FULL_VERSION)
|
||||
|
||||
build-linux: build-native-linux
|
||||
echo :: Building application
|
||||
./node_modules/.bin/build --linux --em.version=$(FULL_VERSION)
|
||||
|
||||
package-windows-app:
|
||||
echo :: Building app MSI $(SHORT_VERSION)
|
||||
heat dir dist/win-unpacked/ -cg Files -gg -scom -sreg -sfrag -srd -dr INSTALLDIR -var var.SourceDir -out build/files.wxs
|
||||
candle -dSourceDir=dist\\win-unpacked -dProductVersion=$(SHORT_VERSION) -arch x64 -o dist/ build/files.wxs build/windows/elements.wxs
|
||||
light -o dist/elements-app.msi dist/files.wixobj dist/elements.wixobj
|
||||
build/windows/signtool.exe sign /f "build\\certificates\\Code Signing.p12" dist/elements-app.msi
|
||||
|
||||
package-windows-bundle:
|
||||
echo :: Building installer
|
||||
candle -dVersion=$(SHORT_VERSION) -ext WixBalExtension -arch x64 -o dist/build.wixobj build/windows/build.wxs
|
||||
light -ext WixBalExtension -o bundle.exe dist/build.wixobj
|
||||
insignia -ib bundle.exe -o engine.exe
|
||||
build/windows/signtool.exe sign /f "build\\certificates\\Code Signing.p12" engine.exe
|
||||
insignia -ab engine.exe bundle.exe -o dist/Elements-Electron.exe
|
||||
build/windows/signtool.exe sign /f "build\\certificates\\Code Signing.p12" dist/Elements-Electron.exe
|
||||
rm engine.exe bundle.exe || true
|
||||
|
||||
package-windows: build-windows package-windows-app package-windows-bundle
|
||||
|
||||
package-mac: driver-mac build-mac
|
||||
rm -rf $(MAC_WS) || true
|
||||
mkdir -p $(MAC_WS)
|
||||
mkdir -p $(MAC_WS)/app/Applications
|
||||
mkdir -p $(MAC_WS)/driver/Library/Extensions
|
||||
cp -Rv dist/mac/ELEMENTS.app $(MAC_WS)/app/Applications/
|
||||
cp -Rv dist/ElementsDriver.kext $(MAC_WS)/driver/Library/Extensions
|
||||
pkgbuild --root $(MAC_WS)/app \
|
||||
--component-plist ./build/mac/Elements.component.plist \
|
||||
--version $(SHORT_VERSION) \
|
||||
--scripts ./build/mac \
|
||||
$(MAC_WS)/Elements.pkg
|
||||
pkgbuild --root $(MAC_WS)/driver \
|
||||
--component-plist ./build/mac/ElementsDriver.component.plist \
|
||||
--scripts ./build/mac \
|
||||
$(MAC_WS)/ElementsDriver.pkg
|
||||
cp ./build/mac/AFPTuner.pkg $(MAC_WS)/
|
||||
|
||||
productbuild --distribution "./build/mac/Distribution.xml" \
|
||||
--package-path $(MAC_WS) \
|
||||
--version $(SHORT_VERSION) \
|
||||
--sign "Developer ID Installer: Syslink GmbH (V4JSMC46SY)" \
|
||||
$(MAC_OUTPUT)
|
||||
|
||||
.PHONY: run native build coverage
|
22
README.md
Normal file
|
@ -0,0 +1,22 @@
|
|||
[![build status](http://ci.elements.tv/root/elements-benchmark/badges/master/build.svg)](http://ci.elements.tv/root/elements-benchmark/commits/master)
|
||||
|
||||
This repository hosts the ELEMENTS Benchmark
|
||||
|
||||
Build requirements:
|
||||
|
||||
* Windows: NodeJS, Windows SDK, WiX on $PATH, Cygwin with ``make`` on $PATH
|
||||
* Mac: NodeJS, Xcode
|
||||
* Linux: NodeJS
|
||||
|
||||
|
||||
Preparing:
|
||||
|
||||
* ``npm install``
|
||||
* ``typings install``
|
||||
* ``webpack``
|
||||
|
||||
Building:
|
||||
|
||||
* Windows: ``make package-windows`` → ``dist/Elements-Electron.exe``
|
||||
* Mac: ``make package-mac`` → ``dist/Elements-Electron.pkg``
|
||||
* Linux: ``make package-linux`` → ``dist/Elements-Electron.AppImage``
|
58
app/assets/bootstrap/bootstrap.less
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Core variables and mixins
|
||||
@import "../../../node_modules/bootstrap/less/variables.less";
|
||||
@import "variables.less";
|
||||
@import "../../../node_modules/bootstrap/less/mixins.less";
|
||||
//@import "mixin-overrides.less";
|
||||
|
||||
// Reset and dependencies
|
||||
@import "../../../node_modules/bootstrap/less/normalize.less";
|
||||
@import "../../../node_modules/bootstrap/less/print.less";
|
||||
@import "../../../node_modules/bootstrap/less/glyphicons.less";
|
||||
|
||||
// Core CSS
|
||||
@import "../../../node_modules/bootstrap/less/scaffolding.less";
|
||||
@import "../../../node_modules/bootstrap/less/type.less";
|
||||
@import "../../../node_modules/bootstrap/less/code.less";
|
||||
@import "../../../node_modules/bootstrap/less/grid.less";
|
||||
@import "../../../node_modules/bootstrap/less/tables.less";
|
||||
@import "../../../node_modules/bootstrap/less/forms.less";
|
||||
@import "../../../node_modules/bootstrap/less/buttons.less";
|
||||
|
||||
// Components
|
||||
@import "../../../node_modules/bootstrap/less/component-animations.less";
|
||||
@import "../../../node_modules/bootstrap/less/dropdowns.less";
|
||||
@import "../../../node_modules/bootstrap/less/button-groups.less";
|
||||
@import "../../../node_modules/bootstrap/less/input-groups.less";
|
||||
@import "../../../node_modules/bootstrap/less/navs.less";
|
||||
@import "../../../node_modules/bootstrap/less/navbar.less";
|
||||
@import "../../../node_modules/bootstrap/less/breadcrumbs.less";
|
||||
@import "../../../node_modules/bootstrap/less/pagination.less";
|
||||
@import "../../../node_modules/bootstrap/less/pager.less";
|
||||
@import "../../../node_modules/bootstrap/less/labels.less";
|
||||
@import "../../../node_modules/bootstrap/less/badges.less";
|
||||
@import "../../../node_modules/bootstrap/less/jumbotron.less";
|
||||
@import "../../../node_modules/bootstrap/less/thumbnails.less";
|
||||
@import "../../../node_modules/bootstrap/less/alerts.less";
|
||||
@import "../../../node_modules/bootstrap/less/progress-bars.less";
|
||||
@import "../../../node_modules/bootstrap/less/media.less";
|
||||
@import "../../../node_modules/bootstrap/less/list-group.less";
|
||||
@import "../../../node_modules/bootstrap/less/panels.less";
|
||||
@import "../../../node_modules/bootstrap/less/responsive-embed.less";
|
||||
@import "../../../node_modules/bootstrap/less/wells.less";
|
||||
@import "../../../node_modules/bootstrap/less/close.less";
|
||||
|
||||
// Components w/ JavaScript
|
||||
@import "../../../node_modules/bootstrap/less/modals.less";
|
||||
@import "../../../node_modules/bootstrap/less/tooltip.less";
|
||||
@import "../../../node_modules/bootstrap/less/popovers.less";
|
||||
@import "../../../node_modules/bootstrap/less/carousel.less";
|
||||
|
||||
// Utility classes
|
||||
@import "../../../node_modules/bootstrap/less/utilities.less";
|
||||
@import "../../../node_modules/bootstrap/less/responsive-utilities.less";
|
||||
|
||||
@import "overrides.less";
|
||||
|
||||
body {
|
||||
background: transparent;
|
||||
}
|
4
app/assets/bootstrap/include.less
Normal file
|
@ -0,0 +1,4 @@
|
|||
// Core variables and mixins
|
||||
@import "../../../node_modules/bootstrap/less/variables.less";
|
||||
@import "variables.less";
|
||||
@import "../../../node_modules/bootstrap/less/mixins.less";
|
541
app/assets/bootstrap/overrides.less
Normal file
|
@ -0,0 +1,541 @@
|
|||
@import (less, reference) "../../../node_modules/font-awesome/css/font-awesome.css";
|
||||
|
||||
|
||||
.glyphicon:extend(.fa all) {
|
||||
&.glyphicon-chevron-right:extend(.fa-chevron-right all) {};
|
||||
&.glyphicon-chevron-left:extend(.fa-chevron-left all) {};
|
||||
&.glyphicon-chevron-up:extend(.fa-chevron-up all) {};
|
||||
&.glyphicon-chevron-down:extend(.fa-chevron-down all) {};
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
|
||||
a {
|
||||
color: #EFEAB1;
|
||||
transition: opacity 0.125s, background 0.125s, color0.125s ;
|
||||
|
||||
&:hover {
|
||||
color: #FFF79A;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.block-element {
|
||||
display: block;
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.btn {
|
||||
border: none !important;
|
||||
box-shadow: 0 1px 1px rgba(0,0,0,.125);
|
||||
|
||||
&:active {
|
||||
outline: 5px auto @brand-info;
|
||||
}
|
||||
|
||||
&:active,
|
||||
&.active {
|
||||
.box-shadow(@control-shadow-active);
|
||||
}
|
||||
|
||||
-webkit-transition: all 0.125s ease-out;
|
||||
-moz-transition: all 0.125s ease-out;
|
||||
-ms-transition: all 0.125s ease-out;
|
||||
-o-transition: all 0.125s ease-out;
|
||||
transition: all 0.125s ease-out;
|
||||
|
||||
&[disabled] {
|
||||
cursor: default !important;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-ink {
|
||||
background: transparent !important;
|
||||
box-shadow: none;
|
||||
|
||||
&.btn-danger {
|
||||
color: #FF4832;
|
||||
}
|
||||
|
||||
&.btn-xs {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-toolbar {
|
||||
margin: 0;
|
||||
|
||||
.btn, .btn-group, [uib-dropdown] {
|
||||
float: none;
|
||||
}
|
||||
|
||||
> .btn-group > * {
|
||||
float: left;
|
||||
}
|
||||
|
||||
> .btn, > .btn-group, > [uib-dropdown] {
|
||||
margin: 0 5px 5px 0px;
|
||||
vertical-align: top;
|
||||
|
||||
> .btn {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: @screen-xs-max) {
|
||||
.btn-toolbar-collapsible {
|
||||
.btn {
|
||||
font-size: 0;
|
||||
|
||||
.fa::before, .caret {
|
||||
font-size: @font-size-base;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[uib-dropdown] {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
[uib-dropdown-menu], .dropdown-menu {
|
||||
.box-shadow(@control-dropdown-shadow);
|
||||
top: 25px;
|
||||
|
||||
> li > * {
|
||||
display: block;
|
||||
padding: 5px 20px;
|
||||
clear: both;
|
||||
font-weight: normal;
|
||||
line-height: @line-height-base;
|
||||
color: @dropdown-link-color;
|
||||
white-space: nowrap;
|
||||
|
||||
&[disabled] {
|
||||
color: #888;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
> li.disabled a {
|
||||
color: #666;
|
||||
&:hover {
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[uib-dropdown-menu] > .active > * {
|
||||
&,
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: @dropdown-link-active-color;
|
||||
text-decoration: none;
|
||||
outline: 0;
|
||||
background-color: @dropdown-link-active-bg;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.form-control {
|
||||
border: none;
|
||||
|
||||
&[checkbox] {
|
||||
border: none;
|
||||
background: transparent;
|
||||
display: inline-block;
|
||||
margin: @padding-base-vertical 0 0;
|
||||
}
|
||||
|
||||
border-radius: 0;
|
||||
.box-shadow(~"0 1px 1px rgba(0, 0, 0, 0.51)");
|
||||
|
||||
&:focus {
|
||||
.box-shadow(~"0 1px 1px rgba(0, 0, 0, 0.51)");
|
||||
}
|
||||
|
||||
.transition(0.25s background);
|
||||
|
||||
&::-webkit-input-placeholder {
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
|
||||
.input-group {
|
||||
.box-shadow(~"0 1px 1px rgba(0, 0, 0, 0.51)");
|
||||
.form-control {
|
||||
.box-shadow(none);
|
||||
}
|
||||
}
|
||||
|
||||
.input-group-addon {
|
||||
border: none;
|
||||
padding: 6px 8px;
|
||||
}
|
||||
|
||||
@media (min-width: @screen-sm-min) {
|
||||
.control-label {
|
||||
font-size: 12px;
|
||||
padding-top: 10px;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.form-group .control-label {
|
||||
font-size: 12px;
|
||||
padding-top: 10px;
|
||||
font-weight: bold;
|
||||
color: #777;
|
||||
}
|
||||
|
||||
label.form-control-static {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.input-group {
|
||||
width: 100%;
|
||||
|
||||
*:focus + .input-group-addon,
|
||||
*:focus + .input-group-btn {
|
||||
//border-bottom: 1px solid @brand-primary;
|
||||
}
|
||||
|
||||
.input-group-addon, .input-group-btn {
|
||||
border: none;
|
||||
|
||||
&.input-sm {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
text-decoration: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 76%;
|
||||
position: relative;
|
||||
padding: 5px 4px 4px;
|
||||
}
|
||||
|
||||
.list-group {
|
||||
.box-shadow(@control-shadow);
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
border: none;
|
||||
border-top: 1px solid @list-group-line-border;
|
||||
cursor: default;
|
||||
|
||||
&:first-child {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: #f7e61d;
|
||||
border-right: 2px solid #f7e61d;
|
||||
}
|
||||
}
|
||||
|
||||
.list-group-item.combi {
|
||||
padding: 0;
|
||||
clear: both;
|
||||
|
||||
tr& {
|
||||
a.main, .btn {
|
||||
display: table-cell !important;
|
||||
}
|
||||
}
|
||||
|
||||
& > .main {
|
||||
display: block;
|
||||
|
||||
h4 {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: transparent;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
video-thumbnail, asset-thumbnail {
|
||||
margin-right: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
& > a.main {
|
||||
cursor: pointer;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
& > a.main, & > a.btn, & > button, & > [uib-dropdown] > button {
|
||||
&:hover,
|
||||
&:focus {
|
||||
text-decoration: none;
|
||||
color: @list-group-link-hover-color;
|
||||
background-color: @list-group-hover-bg;
|
||||
}
|
||||
}
|
||||
|
||||
& > a.btn, & > button, & > [uib-dropdown] > button {
|
||||
background-color: @list-group-bg;
|
||||
position: relative; // more z-index
|
||||
z-index: 2;
|
||||
display: block;
|
||||
float: right;
|
||||
border: none;
|
||||
margin: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
& > .drag-handle {
|
||||
float: left;
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
&.single > .main {
|
||||
height: 40px;
|
||||
line-height: 39px;
|
||||
padding: 0 15px;
|
||||
|
||||
[checkbox] {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.label-lg {
|
||||
top: 7px;
|
||||
}
|
||||
}
|
||||
|
||||
&.double > .main {
|
||||
height: 68px;
|
||||
line-height: 25px;
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
&.single {
|
||||
a.btn, button, .drag-handle {
|
||||
padding: 10px 12px;
|
||||
}
|
||||
}
|
||||
|
||||
&.double {
|
||||
a.btn, button, .drag-handle {
|
||||
padding: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.form-control-focus(@color: @input-border-focus) {
|
||||
@color-rgba: rgba(red(@color), green(@color), blue(@color), .3);
|
||||
}
|
||||
|
||||
.modal {
|
||||
background-color: rgba(0,0,0,.5);
|
||||
position: fixed !important;
|
||||
|
||||
|
||||
.modal-dialog {
|
||||
margin: 0 auto;
|
||||
top: 50px;
|
||||
|
||||
.modal-content {
|
||||
background-color: @body-bg;
|
||||
|
||||
|
||||
.modal-body {
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
padding: 25px 15px;
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
border-top: 1px solid #222;
|
||||
padding: 0;
|
||||
-webkit-app-region: no-drag;
|
||||
|
||||
.btn.btn-default {
|
||||
background: @input-bg;
|
||||
border: none !important;
|
||||
cursor: pointer;
|
||||
box-shadow: none !important;
|
||||
padding: 10px;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0,0,0,.25);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: rgba(0,0,0,.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-backdrop {
|
||||
background: rgba(0,0,0,.25);
|
||||
}
|
||||
|
||||
|
||||
.navbar-fixed-top {
|
||||
border-width: 0 0 2px;
|
||||
height: 52px;
|
||||
}
|
||||
|
||||
.navbar-form {
|
||||
box-shadow: none !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.nav-tabs-justified,
|
||||
.nav-tabs {
|
||||
border-bottom: 1px solid @nav-tabs-border-color;
|
||||
|
||||
> li {
|
||||
> a {
|
||||
border: 1px solid transparent;
|
||||
border-radius: 0;
|
||||
color: @text-color;
|
||||
&:hover {
|
||||
background-color: @nav-tabs-active-link-hover-bg;
|
||||
border-bottom: 1px solid @nav-tabs-border-color;
|
||||
}
|
||||
}
|
||||
|
||||
// Active state, and its :hover to override normal :hover
|
||||
&.active > a {
|
||||
&,
|
||||
&:hover,
|
||||
&:focus {
|
||||
border-radius: 0;
|
||||
border: 1px solid transparent;
|
||||
border-bottom: 1px solid @nav-tabs-active-link-hover-border-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nav-justified {
|
||||
> li {
|
||||
display: table-cell;
|
||||
width: 1%;
|
||||
> a {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.popover-content {
|
||||
//padding: 0;
|
||||
}
|
||||
|
||||
.progress {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
|
||||
table {
|
||||
background: transparent;
|
||||
|
||||
td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.table-condensed {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.table {
|
||||
background: @table-bg;
|
||||
.box-shadow(@control-shadow);
|
||||
&.no-margin {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
> thead,
|
||||
> tbody,
|
||||
> tfoot {
|
||||
> tr {
|
||||
background-color: transparent;
|
||||
> th,
|
||||
> td {
|
||||
border-top: 1px solid @table-line-border-color;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
th, td {
|
||||
border-top: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
> thead > tr > th {
|
||||
border-bottom: 2px solid @table-line-border-color;
|
||||
}
|
||||
}
|
||||
|
||||
.table-bordered {
|
||||
> thead,
|
||||
> tbody,
|
||||
> tfoot {
|
||||
> tr {
|
||||
> th,
|
||||
> td {
|
||||
border: 1px solid @table-line-border-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.help-block {
|
||||
color: darken(@text-color, 10%);
|
||||
}
|
||||
|
||||
|
||||
.label {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
|
||||
.datepicker-dropdown {
|
||||
&.datepicker-orient-top:before {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
&.datepicker-orient-top:after {
|
||||
border-bottom: 7px solid @dropdown-bg !important;
|
||||
}
|
||||
|
||||
&.datepicker-orient-bottom:after {
|
||||
border-top: 7px solid @dropdown-bg !important;
|
||||
}
|
||||
|
||||
table tr td.day:hover {
|
||||
background: #555 !important;
|
||||
}
|
||||
|
||||
table tr td.active {
|
||||
background: @brand-primary !important;
|
||||
color: #222 !important;
|
||||
text-shadow: none !important;
|
||||
}
|
||||
}
|
141
app/assets/bootstrap/variables.less
Normal file
|
@ -0,0 +1,141 @@
|
|||
@brand-primary: #f7e61d;
|
||||
@brand-success: #5cb85c;
|
||||
@brand-info: #5bc0de;
|
||||
@brand-warning: #f0ad4e;
|
||||
@brand-danger: #FF1C01;
|
||||
|
||||
// New
|
||||
@brand-primary: #f7e61d;
|
||||
@brand-success: #42B500;
|
||||
@brand-info: #01BAEF;
|
||||
@brand-warning: #DB8A00;
|
||||
@brand-danger: #EF2F00;
|
||||
|
||||
|
||||
@control-shadow: 0 1px 1px rgba(0,0,0,.25);
|
||||
@control-shadow-active: 0 1px 1px rgba(0,0,0,.25) inset, @control-shadow;
|
||||
@control-dropdown-shadow: 0 0 50px rgba(0,0,0,.5), @control-shadow;
|
||||
@form-accent: #DBCA00;
|
||||
@form-accent-bright: @brand-primary;
|
||||
|
||||
|
||||
@body-bg: #1D272D;
|
||||
@text-color: #aaa;
|
||||
|
||||
@font-family-sans-serif: "Source Sans Pro", "PT Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
@icon-font-path: "../fonts/";
|
||||
@component-active-color: rgba(0,0,0,.15);
|
||||
@component-active-color: darken(@component-active-bg, 30%);
|
||||
@table-bg: #444;
|
||||
@table-bg-accent: rgba(255,255,255,.15);
|
||||
@table-bg-hover: #666;
|
||||
@table-border-color: #2e2e2e;
|
||||
@table-line-border-color: #4f4f4f;
|
||||
|
||||
@btn-default-color: @text-color;
|
||||
@btn-default-bg: #243D49;
|
||||
@btn-default-border: transparent;
|
||||
@btn-primary-color: @component-active-color;
|
||||
@btn-primary-border: #584E00;
|
||||
@btn-danger-border: rgba(0,0,0,.5);
|
||||
@btn-danger-color: white;
|
||||
@btn-danger-bg: #FF4630;
|
||||
@btn-danger-border: transparent;//@brand-danger;
|
||||
@btn-link-disabled-color: darken(@text-color, 20%);
|
||||
|
||||
@input-bg: #11181C;
|
||||
@input-bg-disabled: #2a2f31;
|
||||
@input-color: #bbb;
|
||||
@input-border: #3a3a3a;
|
||||
@input-group-addon-border-color: @input-bg;
|
||||
@input-color-placeholder: #777;
|
||||
@input-group-addon-bg: @input-bg;
|
||||
|
||||
@dropdown-bg: rgba(64,64,64,.95); //@body-bg;
|
||||
@dropdown-link-color: @text-color;
|
||||
@dropdown-link-hover-color: #ddd;
|
||||
@dropdown-link-hover-bg: #444;
|
||||
@dropdown-link-disabled-color: darken(@text-color, 5%);
|
||||
@navbar-default-bg: #23272A;
|
||||
@navbar-default-border: #111;
|
||||
|
||||
|
||||
@nav-tabs-border-color: #666;
|
||||
@nav-tabs-link-hover-border-color: transparent;
|
||||
|
||||
@nav-tabs-active-link-hover-bg: rgba(255,255,255,.1);
|
||||
@nav-tabs-active-link-hover-color: @brand-primary;
|
||||
@nav-tabs-active-link-border-color: @brand-primary;
|
||||
@nav-tabs-active-link-hover-border-color: @brand-primary;
|
||||
|
||||
|
||||
@pagination-color: @btn-default-color;
|
||||
@pagination-bg: @btn-default-bg;
|
||||
@pagination-border: @btn-default-border;
|
||||
|
||||
@pagination-hover-color: @btn-default-color;
|
||||
@pagination-hover-bg: lighten(@btn-default-bg, 5%);
|
||||
@pagination-hover-border: @btn-default-border;
|
||||
|
||||
@pagination-active-color: @brand-primary;
|
||||
@pagination-active-bg: darken(@btn-default-bg, 5%);
|
||||
@pagination-active-border: @btn-default-border;
|
||||
|
||||
@pagination-disabled-color: @btn-link-disabled-color;
|
||||
@pagination-disabled-bg: darken(@btn-default-bg, 5%);
|
||||
@pagination-disabled-border: @btn-default-border;
|
||||
//@state-success-bg: #234116; //#dff0d8;
|
||||
//@state-info-bg: #0C3A50; //#d9edf7;
|
||||
//@state-danger-bg: #9E3B3B;///#f2dede;
|
||||
@popover-bg: rgba(64,64,64,.95);
|
||||
@popover-arrow-color: #444;
|
||||
@progress-bg: #555;
|
||||
@list-group-bg: rgba(255,255,255,.1);
|
||||
@list-group-disabled-bg: #333;
|
||||
@list-group-border: transparent;
|
||||
@list-group-line-border: rgba(255,255,255,.1);
|
||||
@list-group-hover-bg: rgba(255,255,255,.2);
|
||||
@list-group-link-color: @text-color;
|
||||
@list-group-link-heading-color: @text-color;
|
||||
@list-group-active-bg: rgba(255,255,255,.3);
|
||||
@list-group-active-border: transparent;
|
||||
|
||||
|
||||
@panel-bg: @table-bg;
|
||||
@panel-inner-border: @table-border-color;
|
||||
@panel-footer-bg: #666;
|
||||
@panel-default-text: #ddd;
|
||||
@panel-default-border: @table-border-color;
|
||||
@panel-default-heading-bg: #666;
|
||||
@well-bg: #222;
|
||||
@badge-bg: #333;
|
||||
@badge-active-bg: #333;
|
||||
@code-bg: #222;
|
||||
@pre-bg: #222;
|
||||
@pre-color: #bbb;
|
||||
@blockquote-border-color: #444;
|
||||
@page-header-border-color: #444;
|
||||
|
||||
|
||||
@alert-bg: #2A2A2A;
|
||||
|
||||
@state-success-text: @brand-success;
|
||||
@state-success-bg: @alert-bg;
|
||||
@state-success-border: @state-success-text;
|
||||
|
||||
@state-info-text: @brand-info;
|
||||
@state-info-bg: @alert-bg;
|
||||
@state-info-border: @state-info-text;
|
||||
|
||||
@state-warning-text: #F27208;
|
||||
@state-warning-bg: @alert-bg;
|
||||
@state-warning-border: @state-warning-text;
|
||||
|
||||
@state-danger-text: @brand-danger;
|
||||
@state-danger-bg: @alert-bg;
|
||||
@state-danger-border: @state-danger-text;
|
||||
|
||||
|
||||
@border-radius-base: 1px;
|
||||
@border-radius-large: 3px;
|
||||
@border-radius-small: 1px;
|
BIN
app/assets/img/disk.icns
Normal file
BIN
app/assets/img/disk.ico
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
app/assets/img/icon.png
Normal file
After Width: | Height: | Size: 213 KiB |
BIN
app/assets/img/logo.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
107
app/assets/img/logo.svg
Normal file
|
@ -0,0 +1,107 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
xml:space="preserve"
|
||||
width="536.82501"
|
||||
height="126.525"
|
||||
viewBox="0 0 536.82501 126.525"
|
||||
sodipodi:docname="elements_wortmarke+bildmarke_gelb+weiÃ_rz.svg"
|
||||
inkscape:export-filename="/home/eugene/Downloads/logo.png"
|
||||
inkscape:export-xdpi="42.677204"
|
||||
inkscape:export-ydpi="42.677204"><metadata
|
||||
id="metadata8"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs6" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1845"
|
||||
inkscape:window-height="1025"
|
||||
id="namedview4"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.1586643"
|
||||
inkscape:cx="143.54613"
|
||||
inkscape:cy="-3.8338411"
|
||||
inkscape:window-x="75"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g10" /><g
|
||||
id="g10"
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="ink_ext_XXXXXX"
|
||||
transform="matrix(1.25,0,0,-1.25,0,126.525)"><g
|
||||
id="g12"
|
||||
transform="scale(0.1,0.1)"><path
|
||||
d="m 202.457,809.793 404.891,0 0,202.457 -404.891,0 0,-202.457 z"
|
||||
style="fill:#fff200;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path14"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 0,607.375 202.445,0 0,202.457 -202.445,0 0,-202.457 z"
|
||||
style="fill:#fff200;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path16"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 202.457,404.918 404.891,0 0,202.457 -404.891,0 0,-202.457 z"
|
||||
style="fill:#fff200;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path18"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 0,202.461 202.445,0 0,202.457 -202.445,0 0,-202.457 z"
|
||||
style="fill:#fff200;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path20"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 202.457,0 404.891,0 0,202.461 -404.891,0 0,-202.461 z"
|
||||
style="fill:#fff200;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path22"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 1072.96,482.414 -148.108,0 0,48.219 148.108,0 0,-48.219 z m 39.27,-234.23 -302.441,0 0,516.679 302.441,0 0,-48.218 -247.32,0 0,-420.243 247.32,0 0,-48.218"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path24"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 1518.04,248.184 -187.4,0 0,48.218 187.4,0 0,-48.218 z m -247.34,0 -55.1,0 0,516.679 55.1,0 0,-516.679"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path26"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 1875.61,482.414 -148.12,0 0,48.219 148.12,0 0,-48.219 z m 39.27,-234.23 -302.43,0 0,516.679 302.43,0 0,-48.218 -247.33,0 0,-420.243 247.33,0 0,-48.218"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path28"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 2515.65,248.184 -55.12,0 0,333.425 55.12,0 0,-333.425 z m -432.66,0 -55.1,0 0,333.425 55.1,0 0,-333.425"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path30"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 2899.41,482.414 -148.12,0 0,48.219 148.12,0 0,-48.219 z m 39.28,-234.23 -302.44,0 0,516.679 302.44,0 0,-48.218 -247.34,0 0,-420.243 247.34,0 0,-48.218"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path32"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 3438.17,419.605 -55.11,0 0,345.258 55.11,0 0,-345.258 z m -334.12,-171.421 -55.12,0 0,344.457 55.12,0 0,-344.457 z m 336.1,19.675 -44.09,-28.949 -352.46,505.524 44.79,28.933 351.76,-505.508"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path34"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 3732.38,248.184 -55.1,0 0,408.523 55.1,0 0,-408.523 z m 160.52,468.461 -376.14,0 0,48.218 376.14,0 0,-48.218"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path36"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 4243.6,638.805 c -18.61,62.683 -73.02,92.308 -126.76,92.308 -56.49,0 -108.85,-33.754 -108.85,-95.761 0,-37.891 23.43,-75.786 73.02,-86.801 l 16.54,-4.141 -13.1,-48.91 -15.16,3.453 c -75.77,17.902 -115.04,76.461 -115.04,135.02 0,95.757 80.6,144.683 162.59,144.683 73.71,0 148.81,-39.273 171.54,-122.64 L 4243.6,638.805 Z M 4122.34,234.406 c -75.78,0 -153.63,38.571 -181.18,124.696 l 46.84,19.285 c 19.99,-66.137 75.79,-95.762 132.27,-95.762 63.39,0 121.26,37.203 121.26,104.027 0,46.856 -28.24,81.297 -83.37,92.313 l -13.77,2.758 13.08,48.91 19.99,-4.129 c 76.46,-15.848 117.12,-69.586 117.12,-137.777 0,-85.438 -68.9,-154.321 -172.24,-154.321"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path38"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 2528.61,742.93 -44.08,35.597 -211.89,-224.117 -212.58,224.731 -44.08,-35.598 249.15,-263.246 7.51,-7.883 7.51,7.883 248.46,262.633"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path40"
|
||||
inkscape:connector-curvature="0" /></g></g></svg>
|
After Width: | Height: | Size: 6 KiB |
BIN
app/assets/img/shortcut.ico
Normal file
After Width: | Height: | Size: 361 KiB |
BIN
app/assets/img/tray-darwin.png
Normal file
After Width: | Height: | Size: 215 B |
BIN
app/assets/img/tray-darwin@2x.png
Normal file
After Width: | Height: | Size: 241 B |
BIN
app/assets/img/tray-linux.png
Normal file
After Width: | Height: | Size: 261 B |
BIN
app/assets/img/tray-win32.png
Normal file
After Width: | Height: | Size: 261 B |
BIN
app/assets/img/user.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
23
app/assets/toaster-custom.less
Normal file
|
@ -0,0 +1,23 @@
|
|||
app > toaster-container > #toast-container {
|
||||
width: 100% !important;
|
||||
left: 0 !important;
|
||||
right: 0 !important;
|
||||
top: 50px !important;
|
||||
|
||||
.toast {
|
||||
box-shadow: none !important;
|
||||
text-shadow: none !important;
|
||||
opacity: 1 !important;
|
||||
border-radius: 0 !important;
|
||||
width: 100% !important;
|
||||
padding: 10px !important;
|
||||
|
||||
.toaster-icon {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.toast-title {
|
||||
font-weight: normal !important;
|
||||
}
|
||||
}
|
||||
}
|
13
app/index.pug
Normal file
|
@ -0,0 +1,13 @@
|
|||
doctype html
|
||||
html
|
||||
head
|
||||
meta(charset='UTF-8')
|
||||
title ELEMENTS Benchmark
|
||||
base(href='index.html')
|
||||
script.
|
||||
console.timeStamp('index')
|
||||
window.nodeRequire = require
|
||||
script(src='./preload.js')
|
||||
script(src='./bundle.js', defer)
|
||||
body(style='background-image: radial-gradient(circle, #2b3840 0%, #1D272D 100%); min-height: 100vh')
|
||||
app
|
130
app/main.js
Normal file
|
@ -0,0 +1,130 @@
|
|||
const Config = require('electron-config')
|
||||
const electron = require('electron')
|
||||
const platform = require('os').platform()
|
||||
require('electron-debug')({enabled: true, showDevTools: process.argv.indexOf('--debug') != -1})
|
||||
|
||||
let app = electron.app
|
||||
let windowConfig = new Config({name: 'window'})
|
||||
|
||||
|
||||
setupWindowManagement = () => {
|
||||
let windowCloseable
|
||||
|
||||
app.window.on('close', (e) => {
|
||||
windowConfig.set('windowBoundaries', app.window.getBounds())
|
||||
if (!windowCloseable) {
|
||||
app.window.hide()
|
||||
e.preventDefault()
|
||||
}
|
||||
})
|
||||
|
||||
app.window.on('closed', () => {
|
||||
app.window = null
|
||||
})
|
||||
|
||||
electron.ipcMain.on('window-closeable', (event, flag) => {
|
||||
windowCloseable = flag
|
||||
})
|
||||
|
||||
electron.ipcMain.on('window-focus', () => {
|
||||
app.window.show()
|
||||
app.window.focus()
|
||||
})
|
||||
|
||||
app.on('before-quit', () => windowCloseable = true)
|
||||
}
|
||||
|
||||
|
||||
setupMenu = () => {
|
||||
var template = [{
|
||||
label: "Application",
|
||||
submenu: [
|
||||
{ type: "separator" },
|
||||
{ label: "Quit", accelerator: "CmdOrCtrl+Q", click: () => {
|
||||
app.window.webContents.send('host:quit-request')
|
||||
}}
|
||||
]}, {
|
||||
label: "Edit",
|
||||
submenu: [
|
||||
{ label: "Undo", accelerator: "CmdOrCtrl+Z", selector: "undo:" },
|
||||
{ label: "Redo", accelerator: "Shift+CmdOrCtrl+Z", selector: "redo:" },
|
||||
{ type: "separator" },
|
||||
{ label: "Cut", accelerator: "CmdOrCtrl+X", selector: "cut:" },
|
||||
{ label: "Copy", accelerator: "CmdOrCtrl+C", selector: "copy:" },
|
||||
{ label: "Paste", accelerator: "CmdOrCtrl+V", selector: "paste:" },
|
||||
{ label: "Select All", accelerator: "CmdOrCtrl+A", selector: "selectAll:" }
|
||||
]
|
||||
}]
|
||||
|
||||
electron.Menu.setApplicationMenu(electron.Menu.buildFromTemplate(template))
|
||||
}
|
||||
|
||||
|
||||
start = () => {
|
||||
let t0 = Date.now()
|
||||
|
||||
let secondInstance = app.makeSingleInstance((argv) => {
|
||||
app.window.focus()
|
||||
})
|
||||
|
||||
if (secondInstance) {
|
||||
app.quit()
|
||||
return
|
||||
}
|
||||
|
||||
let options = {
|
||||
width: 800,
|
||||
height: 400,
|
||||
icon: `${app.getAppPath()}/assets/img/icon.png`,
|
||||
title: 'ELEMENTS Benchmark',
|
||||
minWidth: 800,
|
||||
minHeight: 400,
|
||||
'web-preferences': {'web-security': false},
|
||||
//- background to avoid the flash of unstyled window
|
||||
backgroundColor: '#1D272D',
|
||||
}
|
||||
Object.assign(options, windowConfig.get('windowBoundaries'))
|
||||
|
||||
if (platform == 'darwin') {
|
||||
options.titleBarStyle = 'hidden'
|
||||
} else {
|
||||
options.frame = false
|
||||
}
|
||||
|
||||
app.commandLine.appendSwitch('--disable-http-cache')
|
||||
|
||||
app.window = new electron.BrowserWindow(options)
|
||||
app.window.loadURL(`file://${app.getAppPath()}/assets/webpack/index.html`, {extraHeaders: "pragma: no-cache\n"})
|
||||
|
||||
if (platform != 'darwin') {
|
||||
app.window.setMenu(null)
|
||||
}
|
||||
|
||||
app.window.show()
|
||||
app.window.focus()
|
||||
|
||||
setupWindowManagement()
|
||||
setupMenu()
|
||||
|
||||
console.info(`Host startup: ${Date.now() - t0}ms`)
|
||||
t0 = Date.now()
|
||||
electron.ipcMain.on('app:ready', () => {
|
||||
console.info(`App startup: ${Date.now() - t0}ms`)
|
||||
})
|
||||
}
|
||||
|
||||
app.on('ready', start)
|
||||
|
||||
app.on('activate', () => {
|
||||
if (!app.window)
|
||||
start()
|
||||
else {
|
||||
app.window.show()
|
||||
app.window.focus()
|
||||
}
|
||||
})
|
||||
|
||||
process.on('uncaughtException', function(err) {
|
||||
console.log(err)
|
||||
app.window.webContents.send('uncaughtException', err)
|
||||
})
|
14
app/package.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"name": "term",
|
||||
"version": "1.0.0",
|
||||
"main": "main.js",
|
||||
"dependencies": {
|
||||
"child-process-promise": "^2.1.3",
|
||||
"devtron": "^1.4.0",
|
||||
"electron-config": "^0.2.1",
|
||||
"electron-debug": "^1.0.1",
|
||||
"electron-is-dev": "^0.1.2",
|
||||
"path": "^0.12.7",
|
||||
"pty.js": "https://github.com/Tyriar/pty.js/tarball/c75c2dcb6dcad83b0cb3ef2ae42d0448fb912642"
|
||||
}
|
||||
}
|
15
app/src/app.d.ts
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
declare var nodeRequire: any
|
||||
interface IPromise {}
|
||||
|
||||
declare interface Window {
|
||||
require: any
|
||||
process: any
|
||||
__dirname: any
|
||||
__platform: any
|
||||
}
|
||||
|
||||
declare var window: Window
|
||||
|
||||
declare interface Console {
|
||||
timeStamp(...args: any[])
|
||||
}
|
60
app/src/app.module.ts
Normal file
|
@ -0,0 +1,60 @@
|
|||
import { NgModule } from '@angular/core'
|
||||
import { BrowserModule } from '@angular/platform-browser'
|
||||
import { HttpModule } from '@angular/http'
|
||||
import { FormsModule } from '@angular/forms'
|
||||
import { ToasterModule } from 'angular2-toaster'
|
||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { PerfectScrollbarModule } from 'angular2-perfect-scrollbar'
|
||||
import { PerfectScrollbarConfigInterface } from 'angular2-perfect-scrollbar'
|
||||
|
||||
const PERFECT_SCROLLBAR_CONFIG: PerfectScrollbarConfigInterface = {
|
||||
suppressScrollX: true
|
||||
}
|
||||
|
||||
|
||||
import { ConfigService } from 'services/config'
|
||||
import { ElectronService } from 'services/electron'
|
||||
import { HostAppService } from 'services/hostApp'
|
||||
import { LogService } from 'services/log'
|
||||
import { ModalService } from 'services/modal'
|
||||
import { NotifyService } from 'services/notify'
|
||||
import { QuitterService } from 'services/quitter'
|
||||
import { LocalStorageService } from 'angular2-localstorage/LocalStorageEmitter'
|
||||
|
||||
import { AppComponent } from 'components/app'
|
||||
import { CheckboxComponent } from 'components/checkbox'
|
||||
import { SettingsModalComponent } from 'components/settingsModal'
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
HttpModule,
|
||||
FormsModule,
|
||||
ToasterModule,
|
||||
NgbModule.forRoot(),
|
||||
PerfectScrollbarModule.forRoot(PERFECT_SCROLLBAR_CONFIG),
|
||||
],
|
||||
providers: [
|
||||
ConfigService,
|
||||
ElectronService,
|
||||
HostAppService,
|
||||
LogService,
|
||||
ModalService,
|
||||
NotifyService,
|
||||
QuitterService,
|
||||
LocalStorageService,
|
||||
],
|
||||
entryComponents: [
|
||||
SettingsModalComponent,
|
||||
],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
CheckboxComponent,
|
||||
SettingsModalComponent,
|
||||
],
|
||||
bootstrap: [
|
||||
AppComponent
|
||||
]
|
||||
})
|
||||
export class AppModule {}
|
132
app/src/components/app.less
Normal file
|
@ -0,0 +1,132 @@
|
|||
@import "~bootstrap/less/variables.less";
|
||||
@import "~bootstrap/variables.less";
|
||||
|
||||
:host {
|
||||
display: flex;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
-webkit-user-select: none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
background: @body-bg;
|
||||
}
|
||||
|
||||
|
||||
.navbar {
|
||||
flex: none;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
border-top: none;
|
||||
-webkit-app-region: drag;
|
||||
margin: 0;
|
||||
|
||||
background: @navbar-default-bg;
|
||||
:host.platform-darwin & {
|
||||
background: fade(@navbar-default-bg, 50%);
|
||||
}
|
||||
|
||||
.navbar-btn-big {
|
||||
margin: 0;
|
||||
padding: 15px 20px 15px;
|
||||
background-color: #333;
|
||||
text-align: left;
|
||||
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
|
||||
&.btn-profile {
|
||||
padding: 7px 14px 7px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
max-width: 150px;
|
||||
|
||||
:host.platform-darwin & {
|
||||
max-width: 120px;
|
||||
}
|
||||
|
||||
>img {
|
||||
flex: none;
|
||||
float: left;
|
||||
margin: 2px 10px 4px 0;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
|
||||
:host.platform-darwin & {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
>div {
|
||||
flex: auto;
|
||||
|
||||
:host.platform-darwin & {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.username {
|
||||
}
|
||||
|
||||
.settings {
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.btn-close {
|
||||
font-size: 38px;
|
||||
padding: 1px 13px 2px;
|
||||
line-height: 47px;
|
||||
|
||||
:host.platform-darwin & {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
button.navbar-btn-big:hover {
|
||||
background-color: #222;
|
||||
}
|
||||
|
||||
button.navbar-btn-big:active {
|
||||
background-color: #111;
|
||||
}
|
||||
|
||||
|
||||
.navbar-brand {
|
||||
padding: 11px 15px;
|
||||
width: 150px;
|
||||
|
||||
:host.platform-darwin & {
|
||||
display: block;
|
||||
margin: auto;
|
||||
float: none;
|
||||
}
|
||||
|
||||
img {
|
||||
height: 28px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[scrollable] {
|
||||
width: 100vw;
|
||||
flex: auto;
|
||||
display: flex;
|
||||
|
||||
.nano {
|
||||
flex: auto;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
display: block;
|
||||
flex: none;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
perfect-scrollbar {
|
||||
flex: auto;
|
||||
min-height: 0;
|
||||
}
|
19
app/src/components/app.pug
Normal file
|
@ -0,0 +1,19 @@
|
|||
div.navbar.navbar-default.draggable
|
||||
button.btn.btn-default.navbar-btn.navbar-btn-big.btn-close.pull-right((click)='hide()', title='Hide')
|
||||
| ×
|
||||
button.btn.btn-default.navbar-btn.navbar-btn-big.pull-right((click)='showSettings()', title='Settings')
|
||||
i.fa.fa-cog
|
||||
div.navbar-brand
|
||||
img.logo(src=require("img/logo.svg"))
|
||||
|
||||
perfect-scrollbar
|
||||
div.container
|
||||
div#term(style='width: 300px; height: 300px;')
|
||||
|
||||
|
||||
footer
|
||||
|
||||
toaster-container([toasterconfig]="toasterconfig")
|
||||
template(ngbModalContainer)
|
||||
|
||||
div.window-resizer.window-resizer-tl
|
87
app/src/components/app.ts
Normal file
|
@ -0,0 +1,87 @@
|
|||
import { Component, ElementRef } from '@angular/core'
|
||||
import { ModalService } from 'services/modal'
|
||||
import { ElectronService } from 'services/electron'
|
||||
import { HostAppService } from 'services/hostApp'
|
||||
import { LogService } from 'services/log'
|
||||
import { QuitterService } from 'services/quitter'
|
||||
import { ToasterConfig } from 'angular2-toaster'
|
||||
|
||||
import { SettingsModalComponent } from 'components/settingsModal'
|
||||
|
||||
import 'angular2-toaster/lib/toaster.css'
|
||||
import 'global.less'
|
||||
|
||||
const hterm = require('hterm-commonjs')
|
||||
var pty = require('pty.js');
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app',
|
||||
template: require('./app.pug'),
|
||||
styles: [require('./app.less')],
|
||||
})
|
||||
export class AppComponent {
|
||||
constructor(
|
||||
private hostApp: HostAppService,
|
||||
private modal: ModalService,
|
||||
private electron: ElectronService,
|
||||
element: ElementRef,
|
||||
log: LogService,
|
||||
_quitter: QuitterService,
|
||||
) {
|
||||
console.timeStamp('AppComponent ctor')
|
||||
|
||||
let logger = log.create('main')
|
||||
logger.info('ELEMENTS client', electron.app.getVersion())
|
||||
|
||||
this.toasterConfig = new ToasterConfig({
|
||||
mouseoverTimerStop: true,
|
||||
preventDuplicates: true,
|
||||
timeout: 4000,
|
||||
})
|
||||
}
|
||||
|
||||
toasterConfig: ToasterConfig
|
||||
|
||||
ngOnInit () {
|
||||
let io
|
||||
hterm.hterm.defaultStorage = new hterm.lib.Storage.Memory()
|
||||
let t = new hterm.hterm.Terminal()
|
||||
t.onTerminalReady = function() {
|
||||
t.installKeyboard()
|
||||
io = t.io.push();
|
||||
//#t.decorate(element.nativeElement);
|
||||
|
||||
var cmd = pty.spawn('bash', [], {
|
||||
name: 'xterm-color',
|
||||
cols: 80,
|
||||
rows: 30,
|
||||
cwd: process.env.HOME,
|
||||
env: process.env
|
||||
});
|
||||
cmd.on('data', function(data) {
|
||||
io.writeUTF8(data);
|
||||
});
|
||||
|
||||
|
||||
io.onVTKeystroke = function(str) {
|
||||
cmd.write(str)
|
||||
};
|
||||
io.sendString = function(str) {
|
||||
cmd.write(str)
|
||||
};
|
||||
io.onTerminalResize = function(columns, rows) {
|
||||
cmd.resize(columns, rows)
|
||||
};
|
||||
};
|
||||
console.log(document.querySelector('#term'))
|
||||
t.decorate(document.querySelector('#term'));
|
||||
}
|
||||
|
||||
ngOnDestroy () {
|
||||
}
|
||||
|
||||
showSettings() {
|
||||
this.modal.open(SettingsModalComponent)
|
||||
}
|
||||
}
|
53
app/src/components/checkbox.less
Normal file
|
@ -0,0 +1,53 @@
|
|||
:host {
|
||||
cursor: pointer;
|
||||
|
||||
&:focus {
|
||||
background: rgba(255,255,255,.05);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: rgba(255,255,255,.1);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.icon {
|
||||
position: relative;
|
||||
flex: none;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
|
||||
i {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 1px;
|
||||
transition: 0.25s opacity;
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
i.on {
|
||||
color: yellow;
|
||||
}
|
||||
|
||||
i.on, &.active i.off {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
i.off, &.active i.on {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
flex: auto;
|
||||
}
|
||||
}
|
4
app/src/components/checkbox.pug
Normal file
|
@ -0,0 +1,4 @@
|
|||
.icon((click)='click()', tabindex='0', [class.active]='model', (keyup.space)='click()')
|
||||
i.fa.fa-square-o.off
|
||||
i.fa.fa-check-square.on
|
||||
.text((click)='click()') {{text}}
|
25
app/src/components/checkbox.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
import { NgZone, Component, Input, Output, EventEmitter } from '@angular/core'
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'checkbox',
|
||||
template: require('./checkbox.pug'),
|
||||
styles: [require('./checkbox.less')]
|
||||
})
|
||||
export class CheckboxComponent {
|
||||
public click() {
|
||||
NgZone.assertInAngularZone()
|
||||
if (this.disabled) {
|
||||
return
|
||||
}
|
||||
|
||||
this.model = !this.model
|
||||
this.modelChange.emit(this.model)
|
||||
}
|
||||
|
||||
@Input() model: boolean
|
||||
@Output() modelChange = new EventEmitter()
|
||||
@Input() disabled: boolean
|
||||
|
||||
@Input() text: string
|
||||
}
|
69
app/src/components/settingsModal.less
Normal file
|
@ -0,0 +1,69 @@
|
|||
:host {
|
||||
>.modal-body {
|
||||
padding: 0 0 20px !important;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.version-info {
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
color: #aaa;
|
||||
cursor: pointer;
|
||||
padding: 10px 0;
|
||||
-webkit-user-select: text;
|
||||
transition: .25s all;
|
||||
|
||||
&:hover {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.status-line {
|
||||
display: flex;
|
||||
padding: 5px 10px;
|
||||
|
||||
&.clickable {
|
||||
&:hover {
|
||||
background: rgba(0,0,0,.5);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
flex: none;
|
||||
padding: 7px 10px 0 0px;
|
||||
|
||||
img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
i {
|
||||
width: 32px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.main {
|
||||
flex: auto;
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
|
||||
.title {
|
||||
flex: none;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.value {
|
||||
flex: auto;
|
||||
font-size: 16px;
|
||||
color: #ddd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
112
app/src/components/settingsModal.pug
Normal file
|
@ -0,0 +1,112 @@
|
|||
div.modal-body
|
||||
ngb-tabset(type='tabs nav-justified')
|
||||
ngb-tab
|
||||
template(ngbTabTitle)
|
||||
i.fa.fa-cog
|
||||
| General
|
||||
template(ngbTabContent)
|
||||
.status-line.clickable(*ngIf='connectionHost', (click)='openWeb()')
|
||||
.icon
|
||||
i.fa.fa-rss.fa-2x.fa-live
|
||||
.main
|
||||
.title Server
|
||||
.value {{connectionHost}}
|
||||
|
||||
.status-line(*ngIf='!connectionHost')
|
||||
.icon
|
||||
i.fa.fa-rss.fa-2x
|
||||
.main
|
||||
.title Server
|
||||
.value Not connected
|
||||
|
||||
.status-line(*ngIf='!userInfo?.user')
|
||||
.icon
|
||||
img(src=require("img/user.png"))
|
||||
.main
|
||||
.title Login
|
||||
.value Not logged in
|
||||
|
||||
.status-line(*ngIf='userInfo?.user')
|
||||
.icon
|
||||
img([src]='userInfo.user.avatar || "../../assets/img/user.png"')
|
||||
.main
|
||||
.title Login
|
||||
.value {{ userInfo.user.full_name || userInfo.user.username }}
|
||||
|
||||
br
|
||||
|
||||
div.form-group
|
||||
checkbox(text='Remember connected workspaces', '[(model)]'='config.store.rememberWorkspaces')
|
||||
ngb-tab
|
||||
template(ngbTabTitle)
|
||||
i.fa.fa-wrench
|
||||
| Advanced
|
||||
template(ngbTabContent)
|
||||
div.form-group(*ngIf='isWindows || isLinux')
|
||||
div.input-group
|
||||
input.form-control(type='text', placeholder='SNFS projects folder', '[(ngModel)]'='config.store.snfsPath')
|
||||
div.input-group-btn
|
||||
button.btn.btn-default((click)='selectSNFSPath()')
|
||||
i.fa.fa-folder-open
|
||||
div.form-group(*ngIf='isWindows')
|
||||
label First drive letter to use
|
||||
select.form-control('[(ngModel)]'='config.store.firstDrive')
|
||||
option(*ngFor='let x of drives', value='{{x}}') {{x}}:
|
||||
div.form-group(*ngIf='isMac')
|
||||
label Extra NFS options
|
||||
input.form-control(type='text', '[(ngModel)]'='config.store.extraNFSOptions')
|
||||
div.form-group(*ngIf='isMac')
|
||||
label Extra AFP options
|
||||
input.form-control(type='text', '[(ngModel)]'='config.store.extraAFPOptions')
|
||||
div.form-group(*ngIf='isMac')
|
||||
label Extra SMB options
|
||||
input.form-control(type='text', '[(ngModel)]'='config.store.extraSMBOptions')
|
||||
div.form-group(*ngIf='isLinux')
|
||||
label Extra NFS options
|
||||
input.form-control(type='text', '[(ngModel)]'='config.store.extraLinuxNFSOptions')
|
||||
div.form-group(*ngIf='isLinux')
|
||||
label Extra SMB options
|
||||
input.form-control(type='text', '[(ngModel)]'='config.store.extraLinuxSMBOptions')
|
||||
|
||||
ngb-tab(*ngIf="apiServer.authorizedKeysStore.length > 0")
|
||||
template(ngbTabTitle)
|
||||
i.fa.fa-plug
|
||||
| Apps
|
||||
template(ngbTabContent)
|
||||
.list-group
|
||||
.list-group-item(*ngFor="let key of apiServer.authorizedKeysStore")
|
||||
button.btn.btn-default((click)='apiServer.deauthorizeKey(key)')
|
||||
i.fa.fa-times
|
||||
span Disconnect this app
|
||||
div {{key.name}}
|
||||
|
||||
ngb-tab
|
||||
template(ngbTabTitle)
|
||||
i.fa.fa-info-circle
|
||||
| About
|
||||
template(ngbTabContent)
|
||||
.form-group
|
||||
h1 ELEMENTS Client
|
||||
div syslink GmbH © {{year}}
|
||||
|
||||
.form-group
|
||||
label Version
|
||||
div {{version}}
|
||||
|
||||
.form-group
|
||||
button.btn.btn-default((click)='copyDiagnostics()') Copy diagnostic info
|
||||
|
||||
div.modal-footer
|
||||
div.btn-group.btn-group-justified
|
||||
a.btn.btn-default((click)='logout()', *ngIf='elementsClient.userInfo')
|
||||
i.fa.fa-fw.fa-arrow-left
|
||||
br
|
||||
| Log out
|
||||
a.btn.btn-default((click)='quit()')
|
||||
i.fa.fa-fw.fa-power-off
|
||||
br
|
||||
| Quit
|
||||
a.btn.btn-default((click)='close()')
|
||||
i.fa.fa-fw.fa-check
|
||||
br
|
||||
| Done
|
44
app/src/components/settingsModal.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
import { Component } from '@angular/core'
|
||||
import { ElectronService } from 'services/electron'
|
||||
import { HostAppService, PLATFORM_WINDOWS, PLATFORM_LINUX, PLATFORM_MAC } from 'services/hostApp'
|
||||
import { ConfigService } from 'services/config'
|
||||
import { QuitterService } from 'services/quitter'
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
|
||||
import * as os from 'os'
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'settings-modal',
|
||||
template: require('./settingsModal.pug'),
|
||||
styles: [require('./settingsModal.less')],
|
||||
})
|
||||
export class SettingsModalComponent {
|
||||
constructor(
|
||||
private modalInstance: NgbActiveModal,
|
||||
private hostApp: HostAppService,
|
||||
private electron: ElectronService,
|
||||
private quitter: QuitterService,
|
||||
public config: ConfigService,
|
||||
) {
|
||||
this.isWindows = hostApp.platform == PLATFORM_WINDOWS
|
||||
this.isMac = hostApp.platform == PLATFORM_MAC
|
||||
this.isLinux = hostApp.platform == PLATFORM_LINUX
|
||||
this.version = electron.app.getVersion()
|
||||
this.year = new Date().getFullYear()
|
||||
}
|
||||
|
||||
isWindows: boolean
|
||||
isMac: boolean
|
||||
isLinux: boolean
|
||||
year: number
|
||||
version: string
|
||||
|
||||
ngOnDestroy() {
|
||||
this.config.save()
|
||||
}
|
||||
|
||||
close() {
|
||||
this.modalInstance.close()
|
||||
}
|
||||
}
|
6
app/src/entry.preload.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
import 'source-sans-pro'
|
||||
|
||||
import 'font-awesome/css/font-awesome.css'
|
||||
|
||||
import '../assets/toaster-custom.less'
|
||||
import '../assets/bootstrap/bootstrap.less'
|
25
app/src/entry.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
console.timeStamp('entry point')
|
||||
|
||||
import 'core-js'
|
||||
import 'zone.js/dist/zone.js'
|
||||
import 'core-js/es7/reflect'
|
||||
import 'jquery'
|
||||
|
||||
// Always land on the start view
|
||||
location.hash = ''
|
||||
|
||||
import { AppModule } from 'app.module'
|
||||
import { enableProdMode } from '@angular/core'
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'
|
||||
|
||||
if (nodeRequire('electron-is-dev')) {
|
||||
console.warn('Running in debug mode')
|
||||
} else {
|
||||
enableProdMode()
|
||||
}
|
||||
|
||||
console.timeStamp('angular bootstrap started')
|
||||
platformBrowserDynamic().bootstrapModule(AppModule)
|
||||
|
||||
|
||||
process.emitWarning = function () { console.log(arguments) }
|
176
app/src/global.less
Normal file
|
@ -0,0 +1,176 @@
|
|||
@import "~bootstrap/include.less";
|
||||
|
||||
|
||||
html.platform-win32 {
|
||||
body.focused {
|
||||
//border: 1px solid #9c9c00 !important;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
border: 1px solid #131313;
|
||||
transition: 0.5s border;
|
||||
overflow: hidden;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.no-drag, a, button, checkbox, .form-control, #toast-container {
|
||||
-webkit-app-region: no-drag;
|
||||
outline: 0 !important;
|
||||
|
||||
* {
|
||||
outline: 0 !important;
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
}
|
||||
|
||||
.form-control {
|
||||
-webkit-user-select: initial;
|
||||
}
|
||||
|
||||
.window-resizer {
|
||||
-webkit-app-region: no-drag;
|
||||
position: fixed;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.window-resizer-tl {
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.no-wrap {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.word-wrap {
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
|
||||
#toast-container.toast-top-full-width {
|
||||
width: 100%;
|
||||
top: 50px;
|
||||
|
||||
> div {
|
||||
width: 100%;
|
||||
border-radius: 0;
|
||||
box-shadow: 0 0 2px rgba(0,0,0,.75);
|
||||
opacity: 1;
|
||||
filter: none;
|
||||
}
|
||||
}
|
||||
|
||||
.avatar {
|
||||
margin: 20px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 50px;
|
||||
box-shadow: 0 1px 1px rgba(0,0,0,.5);
|
||||
}
|
||||
|
||||
|
||||
|
||||
.fa-live {
|
||||
color: #7aff00;
|
||||
|
||||
.list-group-item &.fa-2x {
|
||||
top: 10px;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.otp-input {
|
||||
height: 50px;
|
||||
|
||||
input {
|
||||
height: 50px;
|
||||
font-size: 41px;
|
||||
font-family: monospace;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn {
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ngb-modal-backdrop {
|
||||
// ngbmodalwindow has its own, properly animated backdrop
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
ngb-modal-window.fade.in {
|
||||
&.out {
|
||||
opacity: 0;
|
||||
|
||||
.modal-dialog {
|
||||
transform: translate(0, -25%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngb-tabset {
|
||||
>ul.nav-tabs.nav-justified {
|
||||
border-bottom: none;
|
||||
margin-bottom: 10px;
|
||||
background: rgba(0,0,0,.25);
|
||||
|
||||
.nav-item .nav-link {
|
||||
background: transparent;
|
||||
border: none;
|
||||
|
||||
&.active {
|
||||
background: rgba(0,0,0,.5);
|
||||
border-bottom: 1px solid #777;
|
||||
}
|
||||
|
||||
i {
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
margin: 0 0 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
>.tab-content {
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.btn {
|
||||
i + * {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
margin: none;
|
||||
|
||||
> .btn {
|
||||
float: right;
|
||||
margin: -7px -11px 0 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0,0,0,.25);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ps-container.ps-in-scrolling>.ps-scrollbar-y-rail,
|
||||
.ps-container:hover>.ps-scrollbar-y-rail:hover {
|
||||
background: rgba(0,0,0,.5) !important;
|
||||
}
|
88
app/src/services/config.ts
Normal file
|
@ -0,0 +1,88 @@
|
|||
import { Injectable } from '@angular/core'
|
||||
import { HostAppService, PLATFORM_MAC, PLATFORM_WINDOWS } from 'services/hostApp'
|
||||
const Config = nodeRequire('electron-config')
|
||||
const exec = nodeRequire('child-process-promise').exec
|
||||
import * as fs from 'fs'
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class ConfigService {
|
||||
constructor(
|
||||
private hostApp: HostAppService,
|
||||
) {
|
||||
this.config = new Config({name: 'config'})
|
||||
this.load()
|
||||
}
|
||||
|
||||
private config: any
|
||||
private store: any
|
||||
|
||||
migrate() {
|
||||
if (!this.has('migrated')) {
|
||||
if (this.hostApp.platform == PLATFORM_WINDOWS) {
|
||||
let configPath = `${this.hostApp.getPath('documents')}\\.elements.conf`
|
||||
let config = null
|
||||
try {
|
||||
config = JSON.parse(fs.readFileSync(configPath, 'utf-8'))
|
||||
console.log('Migrating configuration:', config)
|
||||
this.set('host', config.Hostname)
|
||||
this.set('username', config.Username)
|
||||
this.set('firstDrive', config.FirstDrive)
|
||||
} catch (err) {
|
||||
console.error('Could not migrate the config:', err)
|
||||
}
|
||||
this.set('migrated', 1)
|
||||
this.save()
|
||||
return Promise.resolve()
|
||||
}
|
||||
if (this.hostApp.platform == PLATFORM_MAC) {
|
||||
return Promise.all([
|
||||
exec('defaults read ~/Library/Preferences/com.syslink.Elements.plist connection_host').then((result) => {
|
||||
this.set('host', result.stdout.trim())
|
||||
}),
|
||||
exec('defaults read ~/Library/Preferences/com.syslink.Elements.plist connection_username').then((result) => {
|
||||
this.set('username', result.stdout.trim())
|
||||
}),
|
||||
]).then(() => {
|
||||
this.set('migrated', 1)
|
||||
this.save()
|
||||
}).catch((err) => {
|
||||
console.error('Could not migrate the config:', err)
|
||||
this.set('migrated', 1)
|
||||
this.save()
|
||||
})
|
||||
}
|
||||
}
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
set(key: string, value: any) {
|
||||
this.save()
|
||||
this.config.set(key, value)
|
||||
this.load()
|
||||
}
|
||||
|
||||
get(key: string): any {
|
||||
this.save()
|
||||
return this.config.get(key)
|
||||
}
|
||||
|
||||
has(key: string): boolean {
|
||||
this.save()
|
||||
return this.config.has(key)
|
||||
}
|
||||
|
||||
delete(key: string) {
|
||||
this.save()
|
||||
this.config.delete(key)
|
||||
this.load()
|
||||
}
|
||||
|
||||
load() {
|
||||
this.store = this.config.store
|
||||
}
|
||||
|
||||
save() {
|
||||
this.config.store = this.store
|
||||
}
|
||||
}
|
39
app/src/services/electron.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
import { Injectable } from '@angular/core'
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class ElectronService {
|
||||
constructor() {
|
||||
if (process.env.TEST_ENV) {
|
||||
this.initTest()
|
||||
} else {
|
||||
this.init()
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
this.electron = require('electron')
|
||||
this.remoteElectron = this.remoteRequire('electron')
|
||||
this.app = this.remoteElectron.app
|
||||
this.dialog = this.remoteElectron.dialog
|
||||
this.shell = this.electron.shell
|
||||
this.clipboard = this.electron.clipboard
|
||||
this.ipcRenderer = this.electron.ipcRenderer
|
||||
}
|
||||
|
||||
initTest() {
|
||||
;
|
||||
}
|
||||
|
||||
remoteRequire(name: string): any {
|
||||
return this.electron.remote.require(name)
|
||||
}
|
||||
|
||||
app: any
|
||||
ipcRenderer: any
|
||||
shell: any
|
||||
dialog: any
|
||||
clipboard: any
|
||||
private electron: any
|
||||
private remoteElectron: any
|
||||
}
|
69
app/src/services/hostApp.ts
Normal file
|
@ -0,0 +1,69 @@
|
|||
import { Injectable, NgZone, EventEmitter } from '@angular/core'
|
||||
import { ElectronService } from 'services/electron'
|
||||
import { Logger, LogService } from 'services/log'
|
||||
|
||||
export const PLATFORM_WINDOWS = 'win32'
|
||||
export const PLATFORM_MAC = 'darwin'
|
||||
export const PLATFORM_LINUX = 'linux'
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class HostAppService {
|
||||
constructor(
|
||||
private zone: NgZone,
|
||||
private electron: ElectronService,
|
||||
log: LogService,
|
||||
) {
|
||||
this.platform = require('os').platform()
|
||||
this.logger = log.create('hostApp')
|
||||
|
||||
electron.ipcRenderer.on('host:quit-request', () => this.zone.run(() => this.quitRequested.emit()))
|
||||
|
||||
electron.ipcRenderer.on('uncaughtException', function(err) {
|
||||
console.error('Unhandled exception:', err)
|
||||
})
|
||||
|
||||
this.ready.subscribe(() => {
|
||||
electron.ipcRenderer.send('app:ready')
|
||||
})
|
||||
}
|
||||
|
||||
platform: string;
|
||||
quitRequested = new EventEmitter<any>()
|
||||
ready = new EventEmitter<any>()
|
||||
|
||||
private logger: Logger;
|
||||
|
||||
getWindow() {
|
||||
return this.electron.app.window
|
||||
}
|
||||
|
||||
getShell() {
|
||||
return this.electron.shell
|
||||
}
|
||||
|
||||
getAppPath() {
|
||||
return this.electron.app.getAppPath()
|
||||
}
|
||||
|
||||
getPath(type: string) {
|
||||
return this.electron.app.getPath(type)
|
||||
}
|
||||
|
||||
openDevTools() {
|
||||
this.electron.app.webContents.openDevTools()
|
||||
}
|
||||
|
||||
setWindowCloseable(flag: boolean) {
|
||||
this.electron.ipcRenderer.send('window-closeable', flag)
|
||||
}
|
||||
|
||||
focusWindow() {
|
||||
this.electron.ipcRenderer.send('window-focus')
|
||||
}
|
||||
|
||||
quit() {
|
||||
this.logger.info('Quitting')
|
||||
this.electron.app.quit()
|
||||
}
|
||||
}
|
25
app/src/services/log.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
import { Injectable } from '@angular/core'
|
||||
|
||||
|
||||
export class Logger {
|
||||
constructor(
|
||||
private name: string,
|
||||
) {}
|
||||
|
||||
log(level: string, ...args: any[]) {
|
||||
args.splice(0, 0, this.name + ':')
|
||||
console[level](...args)
|
||||
}
|
||||
|
||||
debug(...args: any[]) { this.log('debug', ...args) }
|
||||
info(...args: any[]) { this.log('info', ...args) }
|
||||
warn(...args: any[]) { this.log('warn', ...args) }
|
||||
error(...args: any[]) { this.log('error', ...args) }
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class LogService {
|
||||
create (name: string): Logger {
|
||||
return new Logger(name)
|
||||
}
|
||||
}
|
29
app/src/services/modal.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { Injectable, NgZone } from '@angular/core';
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class ModalService {
|
||||
constructor(
|
||||
private zone: NgZone,
|
||||
private ngbModal: NgbModal,
|
||||
) {}
|
||||
|
||||
open(content: any, config?: any) {
|
||||
config = config || {}
|
||||
config.windowClass = 'out'
|
||||
let modal = this.ngbModal.open(content, config)
|
||||
|
||||
let fx = (<any>modal)._removeModalElements.bind(modal);
|
||||
|
||||
(<any>modal)._removeModalElements = () => {
|
||||
(<any>modal)._windowCmptRef.instance.windowClass = 'out'
|
||||
setTimeout(() => fx(), 500)
|
||||
}
|
||||
setTimeout(() => {
|
||||
(<any>modal)._windowCmptRef.instance.windowClass = ''
|
||||
}, 1)
|
||||
|
||||
return modal
|
||||
}
|
||||
}
|
48
app/src/services/notify.ts
Normal file
|
@ -0,0 +1,48 @@
|
|||
import { Injectable } from '@angular/core'
|
||||
import { ToasterService } from 'angular2-toaster'
|
||||
import { LogService } from 'services/log'
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class NotifyService {
|
||||
constructor(
|
||||
private toaster: ToasterService,
|
||||
private log: LogService,
|
||||
) {}
|
||||
|
||||
pop(options) {
|
||||
this.toaster.pop(options)
|
||||
}
|
||||
|
||||
info(title: string, body: string = null) {
|
||||
return this.pop({
|
||||
type: 'info',
|
||||
title, body,
|
||||
timeout: 4000,
|
||||
})
|
||||
}
|
||||
|
||||
success(title: string, body: string = null) {
|
||||
return this.pop({
|
||||
type: 'success',
|
||||
title, body,
|
||||
timeout: 4000,
|
||||
})
|
||||
}
|
||||
|
||||
warning(title: string, body: string = null) {
|
||||
return this.pop({
|
||||
type: 'warning',
|
||||
title, body,
|
||||
timeout: 4000,
|
||||
})
|
||||
}
|
||||
|
||||
error(title: string, body: string = null) {
|
||||
return this.pop({
|
||||
type: 'error',
|
||||
title, body,
|
||||
timeout: 4000,
|
||||
})
|
||||
}
|
||||
}
|
21
app/src/services/quitter.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { Injectable } from '@angular/core'
|
||||
import { HostAppService } from 'services/hostApp'
|
||||
import { ElectronService } from 'services/electron'
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class QuitterService {
|
||||
constructor(
|
||||
private electron: ElectronService,
|
||||
private hostApp: HostAppService,
|
||||
) {
|
||||
hostApp.quitRequested.subscribe(() => {
|
||||
this.quit()
|
||||
})
|
||||
}
|
||||
|
||||
quit() {
|
||||
this.hostApp.setWindowCloseable(true)
|
||||
this.hostApp.quit()
|
||||
}
|
||||
}
|
62
build/config.gypi
Normal file
|
@ -0,0 +1,62 @@
|
|||
# Do not edit. File was generated by node-gyp's "configure" step
|
||||
{
|
||||
"target_defaults": {
|
||||
"cflags": [],
|
||||
"default_configuration": "Release",
|
||||
"defines": [],
|
||||
"include_dirs": [],
|
||||
"libraries": []
|
||||
},
|
||||
"variables": {
|
||||
"asan": 0,
|
||||
"debug_devtools": "node",
|
||||
"force_dynamic_crt": 0,
|
||||
"host_arch": "x64",
|
||||
"icu_data_file": "icudt57l.dat",
|
||||
"icu_data_in": "..\\..\\deps/icu-small\\source/data/in\\icudt57l.dat",
|
||||
"icu_endianness": "l",
|
||||
"icu_gyp_path": "tools/icu/icu-generic.gyp",
|
||||
"icu_locales": "en,root",
|
||||
"icu_path": "deps/icu-small",
|
||||
"icu_small": "true",
|
||||
"icu_ver_major": "57",
|
||||
"node_byteorder": "little",
|
||||
"node_enable_d8": "false",
|
||||
"node_enable_v8_vtunejit": "false",
|
||||
"node_install_npm": "true",
|
||||
"node_module_version": 48,
|
||||
"node_no_browser_globals": "false",
|
||||
"node_prefix": "/usr/local",
|
||||
"node_release_urlbase": "https://nodejs.org/download/release/",
|
||||
"node_shared": "false",
|
||||
"node_shared_cares": "false",
|
||||
"node_shared_http_parser": "false",
|
||||
"node_shared_libuv": "false",
|
||||
"node_shared_openssl": "false",
|
||||
"node_shared_zlib": "false",
|
||||
"node_tag": "",
|
||||
"node_use_bundled_v8": "true",
|
||||
"node_use_dtrace": "false",
|
||||
"node_use_etw": "true",
|
||||
"node_use_lttng": "false",
|
||||
"node_use_openssl": "true",
|
||||
"node_use_perfctr": "true",
|
||||
"node_use_v8_platform": "true",
|
||||
"openssl_fips": "",
|
||||
"openssl_no_asm": 0,
|
||||
"shlib_suffix": "so.48",
|
||||
"target_arch": "x64",
|
||||
"v8_enable_gdbjit": 0,
|
||||
"v8_enable_i18n_support": 1,
|
||||
"v8_inspector": "true",
|
||||
"v8_no_strict_aliasing": 1,
|
||||
"v8_optimized_debug": 0,
|
||||
"v8_random_seed": 0,
|
||||
"v8_use_snapshot": "true",
|
||||
"want_separate_host_toolset": 0,
|
||||
"nodedir": "C:\\cygwin64\\home\\Avid\\.node-gyp\\iojs-1.3.5",
|
||||
"copy_dev_lib": "true",
|
||||
"standalone_static_library": 1,
|
||||
"target": "1.3.5"
|
||||
}
|
||||
}
|
BIN
build/icon.ico
Normal file
After Width: | Height: | Size: 361 KiB |
BIN
build/icons/1024x1024.png
Normal file
After Width: | Height: | Size: 213 KiB |
BIN
build/icons/128x128.png
Normal file
After Width: | Height: | Size: 8.2 KiB |
BIN
build/icons/16x16.png
Normal file
After Width: | Height: | Size: 749 B |
BIN
build/icons/256x256.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
build/icons/32x32.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
build/icons/512x512.png
Normal file
After Width: | Height: | Size: 65 KiB |
BIN
build/icons/64x64.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
build/logo.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
35
build/mac/Distribution.xml
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<installer-gui-script minSpecVersion="1">
|
||||
<title>ELEMENTS Client</title>
|
||||
<options customize="never" require-scripts="true" rootVolumeOnly="true" />
|
||||
|
||||
<choices-outline>
|
||||
<line choice="default">
|
||||
<line choice="com.syslink.elements.driver" />
|
||||
<line choice="com.syslink.Elements" />
|
||||
<line choice="com.syslink.afptuner" />
|
||||
</line>
|
||||
</choices-outline>
|
||||
|
||||
<choice id="default"/>
|
||||
|
||||
<choice id="com.syslink.elements.driver">
|
||||
<pkg-ref id="com.syslink.elements.driver"/>
|
||||
</choice>
|
||||
<pkg-ref id="com.syslink.elements.driver" version="1" auth="root">ElementsDriver.pkg</pkg-ref>
|
||||
|
||||
<choice id="com.syslink.Elements">
|
||||
<pkg-ref id="com.syslink.Elements"/>
|
||||
</choice>
|
||||
<pkg-ref id="com.syslink.Elements" version="1" auth="root">Elements.pkg</pkg-ref>
|
||||
<pkg-ref id="com.syslink.Elements">
|
||||
<must-close>
|
||||
<app id="com.syslink.Elements"/>
|
||||
</must-close>
|
||||
</pkg-ref>
|
||||
|
||||
<choice id="com.syslink.afptuner" title="AvidSharedStorageAccess">
|
||||
<pkg-ref id="com.syslink.afptuner"/>
|
||||
</choice>
|
||||
<pkg-ref id="com.syslink.afptuner" version="1" auth="root">AFPTuner.pkg</pkg-ref>
|
||||
</installer-gui-script>
|
20
build/mac/Elements.component.plist
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<array>
|
||||
<dict>
|
||||
<key>BundleHasStrictIdentifier</key>
|
||||
<true/>
|
||||
<key>BundleIsRelocatable</key>
|
||||
<false/>
|
||||
<key>BundleIsVersionChecked</key>
|
||||
<false/>
|
||||
<key>BundleOverwriteAction</key>
|
||||
<string>upgrade</string>
|
||||
<key>BundlePostInstallScriptPath</key>
|
||||
<string>Elements.postinst.sh</string>
|
||||
<key>RootRelativeBundlePath</key>
|
||||
<string>Applications/ELEMENTS.app</string>
|
||||
</dict>
|
||||
</array>
|
||||
</plist>
|
44
build/mac/Elements.postinst.sh
Executable file
|
@ -0,0 +1,44 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
cat > /Library/LaunchDaemons/com.elements.VolumesFix.plist << EOF
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>KeepAlive</key>
|
||||
<false/>
|
||||
<key>Label</key>
|
||||
<string>com.elements.VolumesFix</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/bin/bash</string>
|
||||
<string>-c</string>
|
||||
<string>sleep 3; chmod 777 /Volumes</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>/dev/null</string>
|
||||
<key>StandardOutPath</key>
|
||||
<string>/dev/null</string>
|
||||
<key>UserName</key>
|
||||
<string>root</string>
|
||||
</dict>
|
||||
</plist>
|
||||
EOF
|
||||
|
||||
chmod 600 /Library/LaunchDaemons/com.elements.VolumesFix.plist
|
||||
|
||||
cat > /etc/nsmb.conf << EOF
|
||||
[default]
|
||||
minauth=none
|
||||
streams=yes
|
||||
soft=yes
|
||||
notify_off=yes
|
||||
port445=no_netbios
|
||||
signing_required=false
|
||||
EOF
|
||||
|
||||
launchctl load -w /Library/LaunchDaemons/com.elements.VolumesFix.plist
|
||||
launchctl start com.elements.VolumesFix
|
50
build/mac/Info.plist
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en_US</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>ELEMENTS</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.syslink.elements</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${VERSION}</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>Elements Client</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>elements-client</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>619</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.8.0</string>
|
||||
<key>LSUIElement</key>
|
||||
<false/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2016 Syslink GmbH. All rights reserved.</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>AtomApplication</string>
|
||||
</dict>
|
||||
</plist>
|
BIN
build/mac/codesign
Executable file
BIN
build/mac/icon.icns
Normal file
34
build/windows/build.wxs
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Wix RequiredVersion="3.6.2830.0" xmlns="http://schemas.microsoft.com/wix/2006/wi"
|
||||
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension">
|
||||
<Bundle Name="ELEMENTS" Version="$(var.Version)" Manufacturer="ELEMENTS.tv" UpgradeCode="508475fc-0e76-4cd1-8e98-6953023ba518"
|
||||
HelpUrl="http://elements.tv"
|
||||
Copyright="Copyright © 2016 ELEMENTS" IconSourceFile="build/icon.ico"
|
||||
AboutUrl="http://elements.tv">
|
||||
|
||||
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.HyperlinkLicense">
|
||||
<bal:WixStandardBootstrapperApplication
|
||||
LicenseUrl=""
|
||||
LogoFile="build\logo.png"
|
||||
ThemeFile="build\windows\wix-theme.xml"
|
||||
/>
|
||||
</BootstrapperApplicationRef>
|
||||
|
||||
<Chain>
|
||||
<MsiPackage
|
||||
Id="ClientMSI"
|
||||
Compressed="yes"
|
||||
ForcePerMachine="yes"
|
||||
SourceFile="dist\elements-app.msi"
|
||||
Vital="yes">
|
||||
</MsiPackage>
|
||||
<MsiPackage
|
||||
Id="DriverMSI"
|
||||
Compressed="yes"
|
||||
ForcePerMachine="yes"
|
||||
SourceFile="build/windows/ElementsDriver_x64.msi"
|
||||
Vital="yes">
|
||||
</MsiPackage>
|
||||
</Chain>
|
||||
</Bundle>
|
||||
</Wix>
|
84
build/windows/elements.wxs
Normal file
|
@ -0,0 +1,84 @@
|
|||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||
<Product Id="*" UpgradeCode="37484543-5276-2386-5427-275941245342"
|
||||
Name="ELEMENTS" Version="$(var.ProductVersion)" Manufacturer="ELEMENTS.tv" Language="1033">
|
||||
<Package InstallerVersion="200"
|
||||
Compressed="yes"
|
||||
Comments="Windows Installer Package"
|
||||
Platform="x64"
|
||||
InstallScope="perMachine"
|
||||
InstallPrivileges="elevated" />
|
||||
<MajorUpgrade AllowDowngrades="yes" Schedule="afterInstallValidate" />
|
||||
<Media Id="1" Cabinet="product.cab" EmbedCab="yes"/>
|
||||
|
||||
<Feature Id="DefaultFeature" Level="1">
|
||||
<ComponentRef Id="RegistryEntries" />
|
||||
<ComponentRef Id="AppDir"/>
|
||||
<ComponentRef Id="AvidSharedStorageAccess"/>
|
||||
<ComponentRef Id="ApplicationShortcutDesktop"/>
|
||||
<ComponentGroupRef Id="Files" />
|
||||
</Feature>
|
||||
|
||||
<Directory Id="TARGETDIR" Name="SourceDir">
|
||||
<Directory Id="DesktopFolder" Name="Desktop">
|
||||
<Component Id="ApplicationShortcutDesktop" Guid="*">
|
||||
<Shortcut Id="ApplicationDesktopShortcut"
|
||||
Name="ELEMENTS"
|
||||
Description="ELEMENTS client app"
|
||||
Target="[INSTALLDIR]\\Elements.exe"
|
||||
WorkingDirectory="INSTALLDIR"/>
|
||||
<RemoveFolder Id="DesktopFolder" On="uninstall"/>
|
||||
<RegistryValue
|
||||
Root="HKCU"
|
||||
Key="Software\ELEMENTS"
|
||||
Name="installed"
|
||||
Type="integer"
|
||||
Value="1"
|
||||
KeyPath="yes"/>
|
||||
</Component>
|
||||
</Directory>
|
||||
<Directory Id="ProgramFiles64Folder">
|
||||
<Directory Id="ElementsDir" Name="ELEMENTS">
|
||||
<Directory Id="INSTALLDIR" Name="ELEMENTS Client">
|
||||
<Component Id="AppDir" Guid="284957a6-a462-4e34-babd-c17800f11054" Win64="yes">
|
||||
<CreateFolder />
|
||||
<!--RemoveFile Id="RemoveFilesFromAppDirectory" Name="*.*" On="uninstall" /-->
|
||||
<!--RemoveFolder Id="AppDir" On="uninstall"/-->
|
||||
</Component>
|
||||
</Directory>
|
||||
</Directory>
|
||||
</Directory>
|
||||
<Component Id="RegistryEntries" Guid="572998d8-719e-4124-8fe6-6d4f8b855d7b">
|
||||
<RegistryKey Root="HKLM"
|
||||
Key="system\currentcontrolset\services\AvidFs"
|
||||
Action="create">
|
||||
<RegistryValue Type="string" Name="Description" Value="AIFMRX" />
|
||||
<RegistryValue Type="string" Name="DisplayName" Value="AIFMRX" />
|
||||
<RegistryValue Type="integer" Name="ErrorControl" Value="1" />
|
||||
<RegistryValue Type="string" Name="Group" Value="Network" />
|
||||
<RegistryValue Type="string" Name="ImagePath" Value="System32\DRIVERS\aifmrx.sys" />
|
||||
<RegistryValue Type="integer" Name="Start" Value="1" />
|
||||
<RegistryValue Type="integer" Name="Type" Value="2" />
|
||||
</RegistryKey>
|
||||
<RegistryKey Root="HKLM"
|
||||
Key="system\currentcontrolset\services\AifMRx\NetworkProvider"
|
||||
Action="create">
|
||||
<RegistryValue Type="string" Name="DeviceName" Value="\Device\AvidFs" />
|
||||
<RegistryValue Type="string" Name="Name" Value="Interface Network" />
|
||||
<RegistryValue Type="string" Name="ProviderPath" Value="System32\aifmrxnp.dll" />
|
||||
</RegistryKey>
|
||||
<RegistryKey Root="HKLM"
|
||||
Key="system\CurrentControlSet\services\LanmanWorkstation\Parameters"
|
||||
Action="create">
|
||||
<RegistryValue Type="integer" Name="DisableLargeMtu" Value="0" KeyPath="yes" />
|
||||
<RegistryValue Type="integer" Name="DisableBandwidthThrottling" Value="1" />
|
||||
<RegistryValue Type="integer" Name="EnableWsd" Value="0" />
|
||||
</RegistryKey>
|
||||
</Component>
|
||||
<Directory Id="System64Folder" Name="SystemFolder">
|
||||
<Component Id="AvidSharedStorageAccess" Guid="972c67f2-ee17-4b20-8939-b92cfa13fcf6" NeverOverwrite="yes" Win64="yes" Permanent="yes">
|
||||
<File Id="AvidSharedStorageAccess.dll" Source="build\windows\AvidSharedStorageAccess.dll" KeyPath="yes"/>
|
||||
</Component>
|
||||
</Directory>
|
||||
</Directory>
|
||||
</Product>
|
||||
</Wix>
|
BIN
build/windows/signtool.exe
Normal file
80
build/windows/wix-theme.xml
Normal file
|
@ -0,0 +1,80 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
|
||||
|
||||
|
||||
<Theme xmlns="http://wixtoolset.org/schemas/thmutil/2010">
|
||||
<Window Width="300" Height="360" HexStyle="100a0000" FontId="0">#(loc.Caption)</Window>
|
||||
<Font Id="0" Height="-12" Weight="500" Foreground="000000" Background="FFFFFF">Segoe UI</Font>
|
||||
<Font Id="1" Height="-24" Weight="500" Foreground="000000">Segoe UI</Font>
|
||||
<Font Id="2" Height="-22" Weight="500" Foreground="666666">Segoe UI</Font>
|
||||
<Font Id="3" Height="-12" Weight="500" Foreground="000000" Background="FFFFFF">Segoe UI</Font>
|
||||
<Font Id="4" Height="-12" Weight="500" Foreground="ff0000" Background="FFFFFF" Underline="yes">Segoe UI</Font>
|
||||
|
||||
<Image X="30" Y="30" Width="256" Height="60" ImageFile="logo.png" Visible="yes"/>
|
||||
|
||||
<Page Name="Help">
|
||||
<Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.HelpHeader)</Text>
|
||||
<Text X="11" Y="112" Width="-11" Height="-35" FontId="3" DisablePrefix="yes">#(loc.HelpText)</Text>
|
||||
<Button Name="HelpCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.HelpCloseButton)</Button>
|
||||
</Page>
|
||||
<Page Name="Install">
|
||||
<!--Hypertext Name="EulaHyperlink" X="11" Y="121" Width="-11" Height="51" TabStop="yes" FontId="3" HideWhenDisabled="yes">#(loc.InstallLicenseLinkText)</Hypertext>
|
||||
<Checkbox Name="EulaAcceptCheckbox" X="-11" Y="-41" Width="260" Height="17" TabStop="yes" FontId="3" HideWhenDisabled="yes">#(loc.InstallAcceptCheckbox)</Checkbox-->
|
||||
<Button Name="InstallButton" X="90" Y="-120" Width="120" Height="50" TabStop="yes" FontId="0">#(loc.InstallInstallButton)</Button>
|
||||
<Button Name="WelcomeCancelButton" X="110" Y="-80" Width="80" Height="23" TabStop="yes" FontId="0">#(loc.InstallCloseButton)</Button>
|
||||
</Page>
|
||||
<Page Name="Options">
|
||||
<Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.OptionsHeader)</Text>
|
||||
<Text X="11" Y="121" Width="-11" Height="17" FontId="3" DisablePrefix="yes">#(loc.OptionsLocationLabel)</Text>
|
||||
<Editbox Name="FolderEditbox" X="11" Y="143" Width="-91" Height="21" TabStop="yes" FontId="3" FileSystemAutoComplete="yes" />
|
||||
<Button Name="BrowseButton" X="-11" Y="142" Width="75" Height="23" TabStop="yes" FontId="3">#(loc.OptionsBrowseButton)</Button>
|
||||
<Button Name="OptionsOkButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.OptionsOkButton)</Button>
|
||||
<Button Name="OptionsCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.OptionsCancelButton)</Button>
|
||||
</Page>
|
||||
<Page Name="FilesInUse">
|
||||
<Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.FilesInUseHeader)</Text>
|
||||
<Text X="11" Y="121" Width="-11" Height="34" FontId="3" DisablePrefix="yes">#(loc.FilesInUseLabel)</Text>
|
||||
<Text Name="FilesInUseText" X="11" Y="150" Width="-11" Height="-86" FontId="3" DisablePrefix="yes" HexStyle="0x0000C000"></Text>
|
||||
|
||||
<Button Name="FilesInUseCloseRadioButton" X="11" Y="-60" Width="-11" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes" HexStyle="0x000009">#(loc.FilesInUseCloseRadioButton)</Button>
|
||||
<Button Name="FilesInUseDontCloseRadioButton" X="11" Y="-40" Width="-11" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes" HexStyle="0x000009">#(loc.FilesInUseDontCloseRadioButton)</Button>
|
||||
|
||||
<Button Name="FilesInUseOkButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.FilesInUseOkButton)</Button>
|
||||
<Button Name="FilesInUseCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.FilesInUseCancelButton)</Button>
|
||||
</Page>
|
||||
<Page Name="Progress">
|
||||
<Text X="30" Y="120" Width="-30" Height="30" FontId="2" DisablePrefix="yes">#(loc.ProgressHeader)</Text>
|
||||
<Text X="30" Y="150" Width="70" Height="17" FontId="3" DisablePrefix="yes">#(loc.ProgressLabel)</Text>
|
||||
<Text Name="OverallProgressPackageText" X="30" Y="200" Width="-30" Height="17" FontId="3" DisablePrefix="yes">#(loc.OverallProgressPackageText)</Text>
|
||||
<Progressbar Name="OverallCalculatedProgressbar" X="30" Y="220" Width="-30" Height="20" />
|
||||
<Button Name="ProgressCancelButton" X="110" Y="-40" Width="80" Height="23" TabStop="yes" FontId="0">#(loc.ProgressCancelButton)</Button>
|
||||
</Page>
|
||||
<Page Name="Modify">
|
||||
<Text X="30" Y="110" Width="-30" Height="30" FontId="2" DisablePrefix="yes">#(loc.ModifyHeader)</Text>
|
||||
|
||||
<Button Name="UninstallButton" X="90" Y="-100" Width="120" Height="50" TabStop="yes" FontId="0">#(loc.ModifyUninstallButton)</Button>
|
||||
<Button Name="RepairButton" X="110" Y="-60" Width="80" Height="23" TabStop="yes" FontId="0">#(loc.ModifyRepairButton)</Button>
|
||||
<Button Name="ModifyCancelButton" X="110" Y="-30" Width="80" Height="23" TabStop="yes" FontId="0">#(loc.ModifyCloseButton)</Button>
|
||||
</Page>
|
||||
<Page Name="Success">
|
||||
<Text Name="SuccessHeader" X="30" Y="110" Width="-30" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">Success</Text>
|
||||
<Text Name="SuccessInstallHeader" X="30" Y="110" Width="-30" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">Installed successfully</Text>
|
||||
<Text Name="SuccessRepairHeader" X="30" Y="110" Width="-30" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">Repaired successfully</Text>
|
||||
<Text Name="SuccessUninstallHeader" X="30" Y="110" Width="-30" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">Uninstalled successfully</Text>
|
||||
|
||||
<Button Name="LaunchButton" X="90" Y="-100" Width="120" Height="50" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.SuccessLaunchButton)</Button>
|
||||
<Button Name="SuccessCancelButton" X="110" Y="-60" Width="80" Height="23" TabStop="yes" FontId="0">#(loc.SuccessCloseButton)</Button>
|
||||
</Page>
|
||||
<Page Name="Failure">
|
||||
<Text Name="FailureHeader" X="30" Y="110" Width="-30" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureHeader)</Text>
|
||||
<Text Name="FailureInstallHeader" X="30" Y="110" Width="-30" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">Setup failed</Text>
|
||||
<Text Name="FailureUninstallHeader" X="30" Y="110" Width="-30" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">Uninstall failed</Text>
|
||||
<Text Name="FailureRepairHeader" X="30" Y="110" Width="-30" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">Repair failed</Text>
|
||||
<Hypertext Name="FailureLogFileLink" X="30" Y="145" Width="-30" Height="50" FontId="3" TabStop="yes" HideWhenDisabled="yes">#(loc.FailureHyperlinkLogText)</Hypertext>
|
||||
<Hypertext Name="FailureMessageText" X="30" Y="195" Width="-30" Height="50" FontId="3" TabStop="yes" HideWhenDisabled="yes" />
|
||||
<Text Name="FailureRestartText" X="-30" Y="255" Width="400" Height="34" FontId="3" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureRestartText)</Text>
|
||||
|
||||
<Button Name="FailureRestartButton" X="90" Y="-100" Width="120" Height="50" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.FailureRestartButton)</Button>
|
||||
<Button Name="FailureCloseButton" X="110" Y="-60" Width="80" Height="23" TabStop="yes" FontId="0">#(loc.FailureCloseButton)</Button>
|
||||
</Page>
|
||||
</Theme>
|
76
package.json
Normal file
|
@ -0,0 +1,76 @@
|
|||
{
|
||||
"name": "term",
|
||||
"devDependencies": {
|
||||
"apply-loader": "^0.1.0",
|
||||
"awesome-typescript-loader": "2.2.4",
|
||||
"css-loader": "0.26.1",
|
||||
"electron": "^1.4.13",
|
||||
"electron-builder": "10.6.1",
|
||||
"electron-osx-sign": "electron-userland/electron-osx-sign#f092181a1bffa2b3248a23ee28447a47e14a8f04",
|
||||
"electron-rebuild": "1.4.0",
|
||||
"file-loader": "^0.9.0",
|
||||
"font-awesome": "4.7.0",
|
||||
"html-loader": "^0.4.4",
|
||||
"less": "^2.7.1",
|
||||
"less-loader": "^2.2.3",
|
||||
"node-gyp": "^3.4.0",
|
||||
"pug-html-loader": "^1.0.9",
|
||||
"pug-loader": "^2.3.0",
|
||||
"pug-static-loader": "0.0.1",
|
||||
"raw-loader": "^0.5.1",
|
||||
"style-loader": "^0.13.1",
|
||||
"to-string-loader": "^1.1.5",
|
||||
"tslint": "4.0.2",
|
||||
"typescript": "2.1.1",
|
||||
"typings": "2.0.0",
|
||||
"url-loader": "^0.5.7",
|
||||
"val-loader": "^0.5.0",
|
||||
"webpack": "2.2.0-rc.0"
|
||||
},
|
||||
"build": {
|
||||
"appId": "com.elements.benchmark",
|
||||
"productName": "ELEMENTS Benchmark",
|
||||
"compression": "normal",
|
||||
"win": {
|
||||
"target": "zip",
|
||||
"icon": "./app/assets/img/shortcut.ico"
|
||||
},
|
||||
"mac": {
|
||||
"category": "public.app-category.video",
|
||||
"icon": "./build/mac/icon.icns",
|
||||
"identity": "Syslink GmbH"
|
||||
},
|
||||
"linux": {
|
||||
"category": "Network",
|
||||
"target": "AppImage",
|
||||
"icon": "./app/assets/img/icon.png"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"pack": "build --dir",
|
||||
"postinstall": "install-app-deps",
|
||||
"dist": "build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@angular/common": "2.3.1",
|
||||
"@angular/compiler": "2.3.1",
|
||||
"@angular/core": "2.3.1",
|
||||
"@angular/forms": "2.3.1",
|
||||
"@angular/http": "2.3.1",
|
||||
"@angular/platform-browser": "2.3.1",
|
||||
"@angular/platform-browser-dynamic": "2.3.1",
|
||||
"@angular/platform-server": "2.3.1",
|
||||
"@angular/router": "3.3.1",
|
||||
"@ng-bootstrap/ng-bootstrap": "^1.0.0-alpha.15",
|
||||
"angular2-localstorage": "github:AilisObrian/angular2-localstorage",
|
||||
"angular2-perfect-scrollbar": "^1.1.0",
|
||||
"angular2-toaster": "^1.1.0",
|
||||
"bootstrap": "^3.3.7",
|
||||
"core-js": "^2.4.1",
|
||||
"jquery": "^3.1.1",
|
||||
"rxjs": "5.0.0-rc.4",
|
||||
"source-sans-pro": "^2.0.10",
|
||||
"hterm-commonjs": "^1.0.0",
|
||||
"zone.js": "0.7.2"
|
||||
}
|
||||
}
|
26
tsconfig.json
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./app/src",
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"declaration": false,
|
||||
"noImplicitAny": false,
|
||||
"removeComments": false,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"sourceMap": true,
|
||||
"noUnusedParameters": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"compileOnSave": false,
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
],
|
||||
"files": [
|
||||
"app/src/app.d.ts",
|
||||
"app/src/entry.ts",
|
||||
"typings/index.d.ts",
|
||||
"node_modules/rxjs/Rx.d.ts"
|
||||
]
|
||||
}
|
22
tslint.json
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"rules": {
|
||||
"indent": [true, "spaces"],
|
||||
"quotemark": [true, "single"],
|
||||
"semicolon": false,
|
||||
"no-inferrable-types": [true, "ignore-params"],
|
||||
"curly": true,
|
||||
"no-duplicate-key": true,
|
||||
"no-duplicate-variable": true,
|
||||
"no-empty": true,
|
||||
"no-eval": true,
|
||||
"no-invalid-this": true,
|
||||
"no-shadowed-variable": true,
|
||||
"no-unreachable": true,
|
||||
"no-unused-expression": true,
|
||||
"no-unused-new": true,
|
||||
"no-unused-variable": true,
|
||||
"no-use-before-declare": true,
|
||||
"no-var-keyword": true,
|
||||
"new-parens": true
|
||||
}
|
||||
}
|
8
typings.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"globalDependencies": {
|
||||
"core-js": "registry:dt/core-js#0.0.0+20160914114559",
|
||||
"electron": "registry:dt/electron#1.3.3+20161012142539",
|
||||
"jquery": "registry:dt/jquery#1.10.0+20160929162922",
|
||||
"node": "registry:dt/node#6.0.0+20161014191813"
|
||||
}
|
||||
}
|
98
webpack.config.js
Normal file
|
@ -0,0 +1,98 @@
|
|||
const path = require("path")
|
||||
const webpack = require("webpack")
|
||||
|
||||
module.exports = {
|
||||
target: 'node',
|
||||
entry: {
|
||||
'index.ignore': 'file-loader?name=index.html!val-loader!pug-html-loader!./app/index.pug',
|
||||
'preload': './app/src/entry.preload.ts',
|
||||
'bundle': './app/src/entry.ts',
|
||||
},
|
||||
devtool: 'source-map',
|
||||
output: {
|
||||
path: 'app/assets/webpack',
|
||||
pathinfo: true,
|
||||
//publicPath: 'assets/webpack/',
|
||||
filename: '[name].js'
|
||||
},
|
||||
resolve: {
|
||||
modules: ['app/src/', 'node_modules', 'app/assets/'],
|
||||
extensions: ['.ts', '.js'],
|
||||
},
|
||||
module: {
|
||||
loaders: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
loader: 'awesome-typescript-loader'
|
||||
},
|
||||
{
|
||||
test: /\.pug$/,
|
||||
exclude: [
|
||||
/index.pug/
|
||||
],
|
||||
loaders: [
|
||||
{
|
||||
loader: 'apply-loader'
|
||||
},
|
||||
{
|
||||
loader: 'pug-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
{ test: /\.css$/, loader: "style-loader!css-loader" },
|
||||
{
|
||||
test: /\.less$/,
|
||||
loader: "style-loader!css-loader!less-loader",
|
||||
exclude: [/app\/src\/components\//],
|
||||
},
|
||||
{
|
||||
test: /\.less$/,
|
||||
loader: "to-string-loader!css-loader!less-loader",
|
||||
include: [/app\/src\/components\//],
|
||||
},
|
||||
{
|
||||
test: /\.(png|svg)$/,
|
||||
loader: "file-loader",
|
||||
query: {
|
||||
name: 'images/[name].[hash:8].[ext]'
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(ttf|eot|otf|woff|woff2)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
|
||||
loader: "file-loader",
|
||||
query: {
|
||||
name: 'fonts/[name].[hash:8].[ext]'
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
externals: {
|
||||
'electron': 'require("electron")',
|
||||
'net': 'require("net")',
|
||||
'remote': 'require("remote")',
|
||||
'shell': 'require("shell")',
|
||||
'ipc': 'require("ipc")',
|
||||
'fs': 'require("fs")',
|
||||
'buffer': 'require("buffer")',
|
||||
'pty.js': 'require("pty.js")',
|
||||
'system': '{}',
|
||||
'file': '{}'
|
||||
},
|
||||
plugins: [
|
||||
new webpack.ProvidePlugin({
|
||||
"window.jQuery": "jquery",
|
||||
}),
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
if (!process.env.DEV) {
|
||||
module.exports.plugins.push(new webpack.LoaderOptionsPlugin({
|
||||
minimize: true,
|
||||
}))
|
||||
module.exports.plugins.push(new webpack.optimize.UglifyJsPlugin({
|
||||
sourceMap: true,
|
||||
mangle: false,
|
||||
}))
|
||||
module.exports.devtool = 'source-map'
|
||||
}
|